我创建了一个微基准测试来比较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 );
}
}
}
在我的系统(沙桥桌面机)上,我得到:
我有点'记录'这个。
mmap + MAP_POPULATE大部分时间都在clear_page_c_e(2M calls / s)中,从__mm_populate调用。我猜这将是页面错误税,如果代码实际上与mmap的内存有关,我将不得不支付,但是...
... malloc(没有将MALLOC_PERTURB_环境变量设置为任何内容)也将大部分时间花在clear_page_c_e上(也是2M调用/ s),但实现了更多的分配/。
带有MALLOC_PERTURB_的calloc和malloc将所有时间花在memset上。我理解为malloc。我认为calloc应该将所有页面映射到所有零的写入时复制页面,但我的glibc显然没有这样做。除了普通mmap之外的所有人都增加了RSS,这对我来说有点令人惊讶。我认为malloc和/或calloc只会在使用内存时执行此操作。