2012-11-20 31 views
0

对于一些精确的测量,我想从命令行中使所有缓存失效/冲洗到RAM(主存储器),以便主程序运行时间评估不受此进程的影响。我发现以下(从here第一个和最后一个):如何从命令行中使所有(数据)缓存失效?

1. echo 3 > /proc/sys/vm/drop_caches 

,我可以建立一个(预执行)程序有以下

2. #include <asm/cachectl.h> 
int cacheflush(char *addr, int nbytes, int cache); 

或我终于可以做一个

3. int main() { 
    const int size = 20*1024*1024; // Allocate 20M. Set much larger then L2 
    char *c = (char *)malloc(size); 
    for (int i = 0; i < 0xffff; i++) 
     for (int j = 0; j < size; j++) 
     c[j] = i*j; 
} 

我的问题是:我需要做什么,哪个版本最好,如果是#2,我应该给它作为起始地址的地址是什么?我的uname -a是Linux 3.2.0-33-generic#52-Ubuntu SMP Thu Oct 18 16:19:45 UTC 2012 i686

回答

3

您正在运行一个操作系统,它会在您背后做其他事情。操作系统将处理中断,在后台运行各种守护进程并执行各种维护任务,并有可能将您的运行进程移至不同的cpu等。

无效缓存是您最担心的问题,如果您的测量必须是这是准确的,您需要重新评估运行测试的环境。即使您设法获得操作系统的所有控制权(基本上意味着将测试代码作为操作系统的一部分),您仍然需要考虑TLB行为和分支预测缓冲区(这些缓冲区会比缓存影响您的性能),获得对SMM的控制权(除非您可以控制BIOS),并了解用于测量的时钟的真实行为(我猜测10度的温度差异会影响您的测量结果,清理缓存)。

换句话说 - 忘记它。衡量事物真实性的一种典型方法是运行“足够”的时间,并取平均值(或最小值或最大值或中值,取决于您想要证明的内容)。

添加更多内容:您的方法编号1刷新文件系统缓存,与cpu上的数据缓存无关。编号2我不知道,我的Linux味道没有它。如果你在你的cpu上有完美的缓存关联性,3号机可能会工作,但你不需要确保操作系统分配的物理页面将触及每条可能的缓存线,而你不能。你还必须确保你在你的测试运行的同一个cpu上执行它,或者在所有cpus上执行它,并且没有任何计划会在两者之间运行。既然你想从命令行运行它,你的shell会在你的程序运行很久以前(并且exec系统调用和文件系统操作不起作用)在整个缓存中跺脚。

在您的架构上可靠地清除缓存的唯一方法是wbinvd指令,因为您不是内核,因此不能调用缓存。

+0

对不起,@艺术,这不是我的问题的答案。 –

+1

@DervinThunk可能不是您想要听到的答案,但它是您需要听到的答案。你的问题揭示了任何现代操作系统都无法满足的假设。我扩展了答案来解决你提到的方法。结论依然存在 - 你不能做你想做的事情,即使你能做到也不会给你预期的结果。 – Art

+1

有一个'CLFLUSH'指令可以用来刷新各个缓存行(可以从用户空间使用);除非您需要对每个MiB内存执行16384次这样的指令(可能会或可能不会)在CPU的缓存中,并且CPU可以(推测性地)在刷新缓存后立即将数据重新提取到缓存中。 – Brendan

相关问题