实验下重复调用栈带来的影响:本来想直接调用,后来想起来这样不能够开辟新的虚存页面,和可能OS会复用之前用过的页面,于是递归一下吧:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#define SMALL_CALL 1025
#define BIG_CALL 100000
static double getCurrentTime()
{
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_sec * 1000 + t.tv_usec * 0.001;
}
int bigStack(int num)
{
int big_array[BIG_CALL];
int sum = 0;
if (num == 0) return 0;
for (int i = 0; i < num; i++) {
sum += big_array[i]++;
}
return bigStack(num - 1);
}
int smallStack(int num)
{
int small_array[SMALL_CALL];
int sum = 0;
if (num == 0) return 0;
for (int i = 0; i < num; i++) {
sum += small_array[i]++;
}
return smallStack(num - 1);
}
static void test(int num)
{
volatile int sum = 0;
int i;
double start, end;
bigStack(num);
start = getCurrentTime();
for (i = 0; i < 10000; i++) {
sum += bigStack(num);
}
end = getCurrentTime();
printf("big\t%.3lfms\n", end - start);
sum = 0; smallStack(num);
start = getCurrentTime();
for (i = 0; i < 10000; i++) {
sum += smallStack(num);
}
end = getCurrentTime();
printf("small\t%.3lfms\n\n", end - start);
}
int main()
{
test(1); test(2); test(4);
test(8); test(16); test(32);
test(64); test(128); test(256);
test(512); test(1024);
return 0;
}
|
编译时关了优化
gcc -std=c99 -O0 source.c -o test
反汇编的代码太多,懒得贴了,从反汇编上看,两部分实验代码完全是一样的,而且确实开辟了相应的栈,因此误差基本上是很小了,唯一注意的就是先跑bigStack时cache还是冷的,预热一下。
执行前ulimit -s unlimited使得栈空间大小不受限制。
实验结果如下
big 0.172ms
small 0.171ms
big 0.337ms
small 0.328ms
big 0.865ms
small 1.083ms
big 3.077ms
small 5.543ms
big 13.017ms
small 11.613ms
big 27.948ms
small 40.222ms
big 88.908ms
small 147.088ms
big 403.671ms
small 639.071ms
big 1371.084ms
small 1801.974ms
big 5860.663ms
small 6410.998ms
说个啥好呢……除掉10000用来平均以后,stack的开辟基本上没有影响时间,太快了,在OS的管理下,这个部分确实基本上可以忽略掉,而且为啥小的还慢一点点?倒过来顺序跑还是一样的,小的慢一点?怀疑是cache缺失造成的,小的内存块比较连续,这样的访存模式,一旦超过了缓存的大小再反复访问,那就是噩梦啊……
阅读(317) | 评论(0) | 转发(0) |