0

我创建了一个微基准来比较 malloc 与 mmap 的分配性能和 RSS 使用情况。

我得出的结论是 mmap 是最快的,除非您实际使用内存。因此,我可能可以将它用于人口稀少的数据结构。

我的问题是这个结论是否正确以及我得出的数字是否有意义(详见下文)。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/time.h>
int main()
{
#define SIZE 100
  void* allocated[SIZE];
  size_t size[SIZE];
  timeval then, now;
  memset(allocated, 0, sizeof allocated );
  gettimeofday(&then, NULL);
  size_t count = 0;
  size_t i = 0;
  for ( ;; )
  {
    if ( allocated[ i ] )
    {
      munmap( allocated[ i ], size[ i ] );
      //free( allocated[ i ] );
    }
    size[ i ] = rand() % 40000000 + 4096;
    allocated[ i ] =
      mmap( NULL, size[ i ],
          PROT_READ | PROT_WRITE,
          MAP_PRIVATE | MAP_ANONYMOUS
          /* | MAP_POPULATE */
        , -1, 0 );
    //allocated[ i ] = malloc( size[ i ] );
    //allocated[ i ] = calloc( 1, size[ i ] );
    //allocated[ i ] = calloc( size[ i ], 1 );
    i = (i+1) % SIZE;
    if ( !( ++count & 0xfff ) )
    {
      gettimeofday(&now, NULL);
      double timedelta = now.tv_sec-then.tv_sec + 1.e-6*( now.tv_usec-then.tv_usec );
      printf( "%f allocations/s\n", count/timedelta );
    }
  }
}

在我的系统(沙桥台式机)上,我得到:

  1. mmap:~900.000 分配/秒,RSS ~0.5 MB,VSIZE ~2GB
  2. mmap + MAP_POPULATE:~800 分配/秒,RSS 和 VSIZE ~2GB
  3. malloc:~280.000 分配/秒,RSS 和 VSIZE ~2GB
  4. calloc:~550 分配/秒,RSS 和 VSIZE ~2GB
  5. malloc, MALLOC_PERTURB_ == 1: ~260 allocations/s, RSS and VSIZE ~2GB

我已经“录制”了一点。

mmap + MAP_POPULATE 大部分时间都在 clear_page_c_e(2M 调用/秒)中,从 __mm_populate 调用。我猜这将是我必须支付的页面错误税,如果代码实际上对mmap'ed内存做了一些事情,但是......

...malloc(没有将 MALLOC_PERTURB_ 环境变量设置为任何内容)也将大部分时间花在 clear_page_c_e 中(也是 2M 调用/秒),但实现了更多的分配/秒。

带有 MALLOC_PERTURB_ 的 calloc 和 malloc 将所有时间都花在 memset 中。我理解malloc。我认为 calloc 应该将所有页面映射到一个全为零的写时复制页面,但我的 glibc 显然没有这样做。

除了普通的 mmap 之外,其他人都增加了 RSS,这让我有点惊讶。我认为 malloc 和/或 calloc 只会在使用内存时这样做。

4

0 回答 0