高速缓存一致性系统会尽最大努力向您隐藏此类信息。我认为您将不得不通过使用性能计数寄存器来检测高速缓存未命中,或者通过使用高分辨率计时器仔细测量读取存储位置的时间来间接观察它。
该程序在我的x86_64机器上运行,以演示的效果
clflush。它使用乘以读取全局变量所需的时间
rdtsc。作为一条直接与CPU时钟相关的指令,可以直接利用它来
rdtsc实现这一目标。
这是输出:
花了81刻花了81刻同花顺:花了387滴答花了72刻
您会看到3次试验:第一个确保
i在高速缓存中(之所以如此,因为它只是作为BSS的一部分被清零了),第二个是读取
i应在高速缓存中的内容。然后将其
clflush踢出
i缓存(及其邻居),并显示重新读取将花费更长的时间。最终读取将验证它是否已返回高速缓存。结果是非常可重现的,并且差异足够大,很容易看到高速缓存未命中。如果您要校准开销,则
rdtsc()可以使差异更加明显。
如果你看不懂,你要测试的内存地址(虽然连
mmap的
/dev/mem应该为这些目的工作)你可以推断出你想要的东西,如果你知道的缓存中的缓存行大小和关联性。然后,您可以使用可访问的内存位置来探查您感兴趣的集合中的活动。
源代码:
#include <stdio.h>#include <stdint.h>inline voidclflush(volatile void *p){ asm volatile ("clflush (%0)" :: "r"(p));}inline uint64_trdtsc(){ unsigned long a, d; asm volatile ("rdtsc" : "=a" (a), "=d" (d)); return a | ((uint64_t)d << 32);}volatile int i;inline voidtest(){ uint64_t start, end; volatile int j; start = rdtsc(); j = i; end = rdtsc(); printf("took %lu ticksn", end - start);}intmain(int ac, char **av){ test(); test(); printf("flush: "); clflush(&i); test(); test(); return 0;}


