有没有办法检查最近是否已刷新处理器缓存?

时间:2011-05-18 07:28:42

标签: linux cpu flush hardware-interface cpu-cache

在i386 linux上。如果可能的话,最好在c /(c / posix std libs)/ proc中。如果没有可以做任何组装或第三方库吗?

编辑:我正在尝试开发测试内核模块是清除缓存行还是整个proccesor(使用wbinvd())。程序以root身份运行,但如果可能,我宁愿留在用户空间。

3 个答案:

答案 0 :(得分:12)

缓存连贯系统尽最大努力向您隐瞒这些内容。我认为你必须通过使用性能计数寄存器来检测高速缓存未命中或者通过使用高分辨率计时器仔细测量读取存储器位置的时间来间接观察它。

此程序适用于我的x86_64框,以演示clflush的效果。它计算使用rdtsc读取全局变量所需的时间。作为直接与CPU时钟绑定的单条指令,可以直接使用rdtsc为理想。

这是输出:

took 81 ticks
took 81 ticks
flush: took 387 ticks
took 72 ticks

你看到3个试验:第一个确保i在缓存中(它是,因为它只是作为BSS的一部分归零),第二个是i的读取应该是在缓存中。然后clflushi踢出缓存(及其邻居)并显示重新读取它需要更长的时间。最终读取将验证它是否已返回缓存中。结果非常可重复,差异足以轻松查看缓存未命中。如果你想要校准rdtsc()的开销,你可以使差异更加明显。

如果您无法读取要测试的内存地址(尽管即使mmap的{​​{1}}也可以用于这些目的),如果您知道缓存行,也可以推断出您想要的内容缓存的大小和关联性。然后,您可以使用可访问的内存位置来探测您感兴趣的集合中的活动。

源代码:

/dev/mem

答案 1 :(得分:3)

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

  1. 我想这是最简单的:如果你有你的内核模块,只需反汇编它,然后查找缓存失效/刷新命令(atm。我想到的只有3个:WBINDVD,CLFLUSH,INVD)。
  2. 你刚才说它适用于i386,但我想你并不是指80386.问题在于有许多不同的扩展和功能。例如。最新的Intel系列包含一些用于缓存系统的性能/分析寄存器,您可以使用它来评估缓存未命中/命中数/传输次数等。
  3. 与2类似,很大程度上取决于您获得的系统。但是,当您拥有多处理器配置时,您可以使用第二个监视第一个缓存一致性协议(MESI)。
  4. 你提到WBINVD - afaik将始终刷新完整的,即所有缓存行

答案 2 :(得分:0)

这可能不是您特定问题的答案,但您是否尝试使用Cachegrind等缓存分析器?它只能用于配置用户空间代码,但您仍然可以使用它,例如,如果函数代码不依赖于任何特定于内核的接口,则将函数代码移动到用户空间。

实际上,这可能比尝试向处理器询问可能存在或可能不存在的信息更有效,并且可能会受到您仅仅询问它的影响 - 是的,Heisenberg在他的时间之前已经过去了: - )