c - 测量访问速度时打印到控制台与文件
问题描述
我正在处理一项以编程方式发现我们计算机上缓存行大小的任务。我知道有命令可以找到它。这不是重点。
我有一个工作示例(至少它显示了我期望的结果)本质上
初始化一个 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。
解决方案
推荐阅读
- html - 如何在我的 PHP 文件中引用我的 MySQL 数据库之一?
- firebase - Firebase“请求”云功能是否也受“冷启动”影响?
- javascript - 为 type.js 实现一个键入时拼写检查器 UI
- php - 如何使用 $_SESSION 变量在 php 页面之间传递随机变量?
- spring - spring-data 默认情况下是否总是在同一个请求中使用相同的持久化上下文?
- clojure - Clojure Spec 和“在 100 次尝试后无法满足这样的谓词......”
- python - 如何替换熊猫数据框中看起来相似的值?
- ruby-on-rails - ActiveStorage 缩略图持久化
- visual-studio - SSDT/VSIX 安装顺序有问题
- c# - .NET C# WebAPI XmlSerialization