灵感来自 Meyers我正在阅读computer cache并想做一个实验来证明上面提到的事情。这是我尝试过的:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
typedef uint8_t data_t;
const uint64_t max = (uint64_t)1<<30;
const unsigned cycles = 1000;
const uint64_t step = 63; // tried also for 64
volatile data_t acu = 0;
volatile data_t *arr = malloc(sizeof(data_t) * max);
for (uint64_t i = 0; i < max; ++i)
arr[i] = ~i;
for(unsigned c = 0; c < cycles; ++c)
for (uint64_t i = 0; i < max; i += step)
acu += arr[i];
printf("%lu\n", max);
return 0;
}
Anbd 然后只是 gcc --std=c99 -O0 test.c && time ./a.out
。我检查过,我的 CPU 缓存行是 64 字节长。通过分配 step = 64
,与 step=63
相比,我尝试更频繁地生成缓存未命中。
但是,step=63
实际上运行得稍微快一些。我怀疑我是预取的“受害者”,因为我的 RAM 读取是顺序的。
我如何改进遍历数组的示例,以演示缓存未命中的成本?
最佳答案
当使用 step = 63
时,您仍然会遇到很多缓存未命中。前两次访问将在同一缓存行上,但接下来的 63 次访问将导致缓存未命中,访问该行的第 63、6、61 ……字节。一种更好的衡量方法是显示 step = 1
(几乎没有缓存未命中)和 step = 64
(总是缓存未命中)之间的差异并调整 max
总访问次数。
关于c - 我如何证明缓存未命中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34816230/