Rom*_*her 10 linux cpu flush hardware-interface cpu-cache
在i386 linux上.如果可能的话,最好在c /(c/posix std libs)/ proc中.如果没有,是否有任何组装或第三方库可以做到这一点?
编辑:我正在尝试开发测试内核模块是否清除缓存行或整个proccesor(使用wbinvd()).程序以root身份运行,但如果可能的话,我宁愿留在用户空间.
Ben*_*son 12
缓存一致系统尽最大努力将这些东西隐藏起来.我认为你必须通过使用性能计数寄存器来检测高速缓存未命中或者通过使用高分辨率计时器仔细测量读取存储器位置的时间来间接观察它.
这个程序适用于我的x86_64盒子来演示它的效果clflush.它计算使用读取全局变量所需的时间rdtsc.作为与CPU时钟直接相关的单指令,可以直接使用rdtsc理想的指令.
took 81 ticks took 81 ticks flush: took 387 ticks took 72 ticks
你看到3个试验:第一个确保i是在缓存中(它是,因为它只是作为BSS的一部分归零),第二个是读取i应该在缓存中.然后clflush踢出i缓存(以及它的邻居)并显示重新读取它需要更长的时间.最终读取将验证它是否已返回缓存中.结果非常可重复,差异足以轻松查看缓存未命中.如果你关心校准开销,rdtsc()你可以使差异更加明显.
如果你看不懂,你想测试(虽然连内存地址mmap的/dev/mem应该为这些目的工作)你可以推断出你想要的东西,如果你知道的缓存中的缓存行大小和关联性.然后,您可以使用可访问的内存位置来探测您感兴趣的集合中的活动.
#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;
}
Run Code Online (Sandbox Code Playgroud)