有没有办法检查最近处理器caching是否被刷新?

在i386 linux上。 如果可能,最好在c /(c / posix std libs)/ proc中。 如果不是有任何可以做到这一点的程序集或第三方库?

编辑:我试图开发testing是否内核模块清除caching行或整个proccesor(与wbinvd())。 程序以root身份运行,但如果可能的话,我宁愿留在用户空间中。

Solutions Collecting From Web of "有没有办法检查最近处理器caching是否被刷新?"

高速缓存一致性系统尽最大努力将这些事情隐藏起来。 我认为你必须间接观察它,要么使用性能计数寄存器来检测缓存未命中,要么使用高分辨率定时器仔细测量读取存储器位置的时间。

这个程序在我的x86_64盒子上工作以演示clflush的效果。 它使用rdtsc读取一个全局变量需要多长时间。 直接连接到CPU时钟的单指令直接使用rdtsc理想的选择。

这是输出:

花了81滴
花了81滴
冲洗:花了387个蜱
花72蜱

你会看到3个试验:第一个确保i在缓存中(这是因为它只是作为BSS的一部分被归零),第二个是i应该在缓存中的读取。 然后clflushi从缓存(及其邻居),并显示重新读取它需要更长的时间。 最后的读取验证它是回到缓存中。 结果是非常可重复的,差异是足够大的容易看到缓存未命中。 如果你关心rdtsc()的开销,你可以使差异更加明显。

如果你不能读取你想测试的内存地址(尽管即使/dev/mem mmap也适用于这些目的),如果知道缓存行的大小和关联性,也许可以推断出你想要的内容。 然后,您可以使用可访问的内存位置来探测您感兴趣的设置中的活动。

源代码:

 #include <stdio.h> #include <stdint.h> inline void clflush(volatile void *p) { asm volatile ("clflush (%0)" :: "r"(p)); } inline uint64_t rdtsc() { unsigned long a, d; asm volatile ("rdtsc" : "=a" (a), "=d" (d)); return a | ((uint64_t)d << 32); } volatile int i; inline void test() { uint64_t start, end; volatile int j; start = rdtsc(); j = i; end = rdtsc(); printf("took %lu ticks\n", end - start); } int main(int ac, char **av) { test(); test(); printf("flush: "); clflush(&i); test(); test(); return 0; } 

我不知道任何通用的命令来获得缓存状态,但有一些方法:

  1. 我想这是最简单的:如果你有你的内核模块,只需要反汇编它,并寻找缓存失效/刷新命令(atm。只是3来到我的脑海里:WBINDVD,CLFLUSH,INVD)。
  2. 你刚才说这是为i386,但我想你不是指一个80386.问题是,有许多不同的扩展和功能不同。 例如,最新的英特尔系列包含一些性能/性能分析寄存器,可用于评估缓存未命中数/命中数/传输次数等。
  3. 类似于2,非常依赖于你得到的系统。 但是当你有一个多处理器的配置,你可以观看第一个缓存一致性协议(MESI)。

您提到了WBINVD – afaik,它总是会刷新完整的,即全部缓存行

这可能不是您的具体问题的答案,但是您是否尝试过使用缓存分析器(例如Cachegrind) ? 它只能用来分析用户空间的代码,但是你也许可以使用它,例如,如果你的函数的代码不依赖于任何特定于内核的接口,那么把你的函数的代码移动到用户空间。

它可能比试图向处理器询问可能存在或不存在的信息更有效,而这些信息可能会受到你单纯询问的影响 – 是的, 海森堡是在他的时间之前呢:-)