对于某些精确测量,我想从命令行使所有高速缓存/刷新到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
答案 0 :(得分:3)
您正在运行的操作系统上执行其他操作。操作系统将处理中断,在后台运行各种守护进程并执行各种维护任务,并可能将正在运行的进程移动到不同的cpu等。
使缓存失效是您最不担心的问题,如果您的测量必须准确无误,则需要重新评估运行测试的环境。即使您设法获得操作系统控制的所有内容(这基本上意味着使您的测试代码成为操作系统的一部分),您仍然需要考虑TLB行为和分支预测缓冲区(这将比缓存更多地影响您的性能),控制SMM(除非你可以控制BIOS,否则你通常不会这样做),并了解你用于测量的时钟是如何表现的(我猜测10度的温差会影响你的测量而不是清理缓存)。
换句话说 - 忘了它。实际测量事物的一种典型方法是“足够”运行它并取平均值(或最小值或最大值或中值,取决于您想要证明的内容)。
添加更多:您的方法号1刷新文件系统缓存,与cpu上的数据缓存无关。 2号我不知道,我的linux风味没有它。如果你的cpu上有完美的缓存关联性,那么3号可能会起作用,你不需要这样做,并且必须确保操作系统分配的物理页面将触及每个可能的缓存行,你不能这样做。您还必须确保在运行测试的同一个cpu上执行它,或者在所有cpu上执行它,并且不会安排在其间运行任何内容。由于您希望从命令行运行此命令,因此您的shell将在程序运行之前很长时间内遍历缓存(并且exec系统调用和文件系统操作无效)。
在您的体系结构上可靠地清除缓存的唯一方法是使用wbinvd指令,因为您不是内核而不应该使用缓存,所以不允许调用它。