我正在做一个作业,以编程方式发现我们计算机上缓存行的大小。我知道有一些命令可以找出答案。这不是重点。
我有一个有效的示例(至少显示了我期望的结果),基本上是
初始化一个10000个元素的int数组,我知道该数组大于我的L1缓存
以1,2,4,8 ... 128的间距访问该数组的1000000个顺序元素,将其添加到全局变量中。我用clock_gettime的差来测量时间,最后加上每个间隔的平均访问时间。
循环结束后,缓存中充满了另一个数组中的值,因此您知道缓存中没有预取主数组中的任何值。
,但是只有当我打印出每次访问终端的时间时,它才是正确的。如果我打印到文件,则不起作用。
我曾尝试创建一个转储文件,其中每个访问的整数,每次计算和总和都将在出现时打印到其中。我认为这将迫使编译器不进行优化和计算。
我曾尝试将10000个元素数组的元素随机化,以免对其进行优化。
我试图在数组中的任意位置开始每个间隔循环,以减少可能的预取。
这是程序的全部内容,可以在https://gist.github.com/jamesamrundle/7142c2e4fbff1971a7308c771ea65b3f中找到完整代码
for (i = 1; i <= 128; i=i*2) {
spacing = i;
r = rand()%10000;
printf("rand = %d",r);
for (j = 0; j < reps; j++) {
// printf("arr[ %d ] ",(0 +(j*i)%10000));
clock_gettime(CLOCK_MONOTONIC, &t1);
sum = sum +arr1[(r +(j*spacing)%10000)];
clock_gettime(CLOCK_MONOTONIC, &t2);
fprintf(xx,"\n\n%d\n",sum);
d = diff_time(&t1, &t2);
timeSum += (d-nullTime);
// timeTotal += (d-nullTime);
// fprintf ( xx,"%d\n",d);<<<<//UNCOMMENT
printf ( "*%d*%d\n",p,d); <<<<//COMMENT OUT
// sleep(1);
}
fprintf (fp, ">>>>>>>>>>>>>>>>spacing of %d, avg run time = %d \n",spacing,timeSum/reps);
arrTimes[k] = (timeSum/reps);
k++;
timeSum = 0;
// sum = 0;
randArray();
floodCache(arr1,xx);
// }
}
因为代码要花很多时间才能执行,因为它会在控制台上打印几百万行。 但是完成后,如果间距为16个元素,您总是会看到一个急剧的跳动
间隔为1,平均运行时间= 26
间隔为2,平均运行时间= 31
间隔为4,平均运行时间= 41
间隔为8,平均运行时间= 53
间隔为16,平均运行时间= 81 <<<-// 16 * sizeof(int)= 64,我的缓存行的大小
间隔为32,平均运行时间= 83
间距为64,平均运行时间= 86
间隔128,平均运行时间= 91
如果注释掉每个数组访问的printf并替换为fprintf,则平均运行时间总是在30以下。