c - malloc 与 mmap 性能

标签 c memory-management malloc mmap

我运行了一个性能测试,将 1.28 亿个整数写入使用 malloc 分配的内存和使用 mmap 映射的内存文件(由磁盘上的文件支持)...我曾预计结果会有些相似,因为我的理解是写入映射内存文件时,数据最初写入内存,pdflush 在后台写入磁盘(以可配置的频率)。使用 malloc,写入 128M 整数需要 0.55 秒; mmap 耗时 1.9 秒。

所以我的问题是:为什么不同。我最初的想法是 pdflush 正在挤满总线,或者当 pdflush 正在访问内存时,它正在阻塞写入......但是,第二次运行 mmap 版本产生了 .52 秒的结果(由于缓存)这导致我相信 mmap 后面的每个页面在被写入之前不会被分配(尽管通过调用 mmap 保留它)......我的理解也是 malloc 产生的内存直到第一次写入才实际分配...... .最初的区别可能是因为在 malloc 初始写入内存之后,分配了整个 block ,而使用 mmap,每次写入新页面时,操作系统必须首先分配它?

更新:

os:CentOS Linux release 7.0.1406 (Core) kernel:3.10.0-123.el7.x86_64 海湾合作委员会:4.8.2

代码:

int* pint = malloc(128000000 * sizeof(int));
int* pint_copy = pint;

clock_t start = clock();

int i;
for(i = 0; i < 128000000; ++i)
{
    *pint++ = i;
}   

clock_t end = clock();

double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("%f\n", cpu_time_used);

free(pint_copy);

对比

int fd = open("db", O_RDWR | O_CREAT, 0666);
const size_t region_size = ((512000000 / sysconf(_SC_PAGE_SIZE)) + 1) * sysconf(_SC_PAGE_SIZE); 

int return_code = ftruncate(fd, region_size);

if (return_code < 0)
    printf("mapped memory file could not be truncated: %u\n", return_code);

int* pint = mmap(NULL, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
int* pint_copy = pint;
close(fd);  

clock_t start = clock();

int i;
for(i = 0; i < 128000000; ++i)
{
    *pint++ = i;
}   

clock_t end = clock();

double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("%f\n", cpu_time_used);

fgetc(stdin);

munmap(pint_copy, region_size);

添加:

int z = 512;
while(z < 128000000)
{
    pint[z] = 0;

    z += 1024;
}

之前:

  clock_t start = clock();     

两次试验都产生 0.37 秒,让我相信“触摸”每个页面会导致操作系统分配物理内存(包括 mmap 和 malloc)......这也可能部分是因为“触摸”页面移动一些要缓存的内存...有谁知道在对内存进行大量写入(长时间)时,pdflush 是否会阻塞或减慢内存写入?

最佳答案

是的,你是对的。使用 mmap 获取的页面在您尝试访问它们之前不会被填充。你不能保证这一点,但通常操作系统使用 write-back (对于这唯一的 yield 没有惩罚)和demand-paging (您必须支付第一次访问费用)。

关于c - malloc 与 mmap 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28097719/

相关文章:

c - strstr 未按预期在循环内工作

python - 在不分配新对象的情况下用特定值填充列表的一部分

c - 我是 "have to"free() 静态动态分配指针吗?

c - 为结构体数组分配空间,并学习一些 C

c - 在STM32F3上用DMA生成正弦波-乱码输出

android - 将字符串从 Java 传递到 C++ 并使用带有 NDK 案例错误的 popen?

c++ - 如何在 C++ 中初始化列表 vector ?

c - 如何在 Linux 上调试内存覆盖

C 动态数组的静态指针

c++ - 获取 'name of the application' 以及按键