我正在对不同的编程语言进行基准测试,发现了一个有趣的问题。堆栈内存和堆内存的 memset 性能不同。我没有发现明显的原因。例如,缺页次数相同,编译出来的二进制代码也相同。测量的时间是访问时间,而不是分配时间。
有什么想法吗?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <string.h>
void perf_test(unsigned char* data, unsigned long total_size)
{
clock_t begin_t, end_t;
begin_t = clock();
memset(data, 1, total_size);
end_t = clock();
double duration = (double) (end_t-begin_t)/CLOCKS_PER_SEC;
printf("Duration %f", duration);
}
int main(int argc, char *argv[])
{
unsigned long total_size = 1024*1024*1024;
// Run the program with some argument to run heap test, or without any argument to run stack test
if (argc > 1) {
printf("Heap test\n");
unsigned char* data = (unsigned char*)malloc(total_size);
perf_test(data, total_size);
free(data);
} else {
printf("Stack test\n");
unsigned char data[total_size];
perf_test(data, total_size);
}
return 0;
}
程序输出:
./stack_heap.exe
Stack test
Duration 0.125000
./stack_heap.exe 1
Heap test
Duration 0.609000
要编译程序,我使用以下命令:
gcc -O3 -Wl,--stack,1500000000 stack_heap.c -o stack_heap
基于堆栈的块将被预先分配,并且将通过
memset()
而不会出现页面错误。您已经告诉过两者的页面错误是相同的,但在基于堆栈的块的情况下不应该发生页面错误。在堆的情况下,在访问之前不会分配内存,因此,memset()
调用实际上会有额外的处理来分配内存。我们可以验证这一点。在 memset()
之前,创建对数据块的一次访问,然后使用 memset()
测量性能