灵感来自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读取是顺序的。
如何改进我走数组的示例,以证明缓存未命中的成本?
答案 0 :(得分:2)
使用find
时,您仍会收到大量缓存未命中。前两次访问将在同一个缓存行上,但接下来的63次访问将导致缓存未命中,访问该行的第63,6,61 ......字节。测量它的更好方法是显示step = 63
(几乎没有缓存未命中)和step = 1
(始终是缓存未命中)之间的差异,并调整step = 64
以获得访问次数总。