Memory management mmap vs malloc vs calloc性能微基准:期待什么
我创建了一个微基准来比较malloc和mmap的分配性能和RSS使用情况 我的结论是mmap是最快的,除非你真的使用内存。因此,我可能会将其用于人口稀少的数据结构 我的问题是这个结论是否正确,我得出的数字是否有意义(详情见下文)Memory management mmap vs malloc vs calloc性能微基准:期待什么,memory-management,malloc,mmap,copy-on-write,Memory Management,Malloc,Mmap,Copy On Write,我创建了一个微基准来比较malloc和mmap的分配性能和RSS使用情况 我的结论是mmap是最快的,除非你真的使用内存。因此,我可能会将其用于人口稀少的数据结构 我的问题是这个结论是否正确,我得出的数字是否有意义(详情见下文) #包括 #包括 #包括 #包括 #包括 int main() { #定义大小100 无效*已分配[大小]; 大小[大小]; 当时,现在; memset(已分配,0,sizeof已分配); gettimeofday(&then,NULL); 大小\u t计数=0; 尺寸i
#包括
#包括
#包括
#包括
#包括
int main()
{
#定义大小100
无效*已分配[大小];
大小[大小];
当时,现在;
memset(已分配,0,sizeof已分配);
gettimeofday(&then,NULL);
大小\u t计数=0;
尺寸i=0;
对于(;;)
{
如果(已分配[i])
{
munmap(分配[i],大小[i]);
//自由(分配[i]);
}
大小[i]=rand()%40000000+4096;
已分配[i]=
mmap(空,大小[i],
保护读,保护写,
MAP|u PRIVATE | MAP|u ANONYMOUS
/*|地图|*/
, -1, 0 );
//分配的[i]=malloc(大小[i]);
//分配的[i]=calloc(1,大小[i]);
//分配的[i]=calloc(大小[i],1);
i=(i+1)%SIZE;
如果(!(++count&0xfff))
{
gettimeofday(&now,NULL);
double timedelta=now.tv_sec-then.tv_sec+1.e-6*(now.tv_usec-then.tv_usec);
printf(“%f分配/s\n”,计数/timedelta);
}
}
}
在我的系统(sandy bridge台式机)上,我得到:
除了普通mmap之外,其他人都增加了RSS,这让我有点惊讶。我认为malloc和/或calloc只在使用内存时才会这样做。分配随机大小的缓冲区是不现实的。程序具有特有的访问模式,如果您想知道程序将如何执行,则需要模拟其访问模式。如果您只想知道
malloc
和mmap
的速度有多快,那么请针对各种固定的分配大小运行此基准测试。@Larsman的观点很好。将mmap更改为使用固定的分配大小不会改变我的系统上的任何内容,但malloc的行为非常不同。malloc'ing 40MB缓冲区的大小仍然为280.000 allocs/s,但没有增长的RSS。malloc'ing 4096字节缓冲区可达到约33.000.000 allocs/s,并且在malloc_扰动_情况下仍能达到4.000.000 allocs/s。这两种方法都比mmap/mmap+MAP更有趣。至少在Linux系统上,malloc
'ing几十兆字节实际上会导致调用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 );
}
}
}