【问题标题】:malloc vs mmap performancemalloc 与 mmap 性能
【发布时间】:2015-03-21 18:32:55
【问题描述】:

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

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

更新:

os:CentOS Linux 版本 7.0.1406(核心)内核:3.10.0-123.el7.x86_64 gcc: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 是否会阻塞或减慢内存写入?

【问题讨论】:

  • 这是非常特定于操作系统(和编译器特定)的,但你没有说你使用的是哪个。
  • Malloc 可能也在内部使用 mmap,请使用 strace 进行检查。它很可能映射一个共享内存对象(参见 shm_open,在最近的 Linux 中,它使用 tmpfs 在 /dev/shm 中打开一个文件)。 mmap 中的 MMAP_POPULATE 标志也可能是相关的。
  • 太多变量可能会影响这一点 - 其他正在运行的东西、CPU 数量、内存可用性、中断、后台 I/O、预读和/或故障前模式,实际 mmap()使用情况(即你是映射/dev/zero还是一个真实的文件或者别的什么,如果是一个真实的文件,它是事先存在的还是需要分配的),等等...

标签: c memory-management malloc mmap


【解决方案1】:

是的,你是对的。使用mmap 获得的页面在您尝试访问它们之前不会被填满。您对此无法保证,但操作系统通常使用write-back(此唯一收益不会受到惩罚)和demand-paging(您必须先支付第一次访问费用)。

【讨论】:

    【解决方案2】:

    我不知道答案,但这在我看来就像是在比较苹果和橙子。

    也就是说,一方面您正在写入(malloc'd)内存,而另一方面您正在写入内存到(mmap'd)磁盘。我预计会引发设备 I/O 活动的第二个比不引发任何 I/O 的第一个慢一个数量级。

    【讨论】:

      猜你喜欢
      • 2010-12-16
      • 1970-01-01
      • 2013-01-25
      • 2017-11-05
      • 2010-11-06
      • 2014-07-20
      • 2015-08-13
      • 1970-01-01
      • 2014-02-02
      相关资源
      最近更新 更多