所以现代计算机和操作系统很复杂,并且有很多东西使得准确的预测和运行时的可重复性变得困难,比如调度器、分支预测器、缓存、预取器等。我不明白这些东西,但我想我理解其中的含义:运行一次是不够的。
幸运的是,perf stat
它提供了一个--repeat
命令,甚至为您提供了基本的统计数据。所以为了测试这个,我跑了
#include <stdio.h>
int main(int argc, char *argv[])
{
puts("Hello, World!");
return 0;
}
gcc -O2 hello.c -o hello
用命令编译perf stat -r 100 ./hello
。这给了我很好的输出像这样
0,00043149 +- 0,00000688 seconds time elapsed ( +- 1,59% )
但是,如果我现在再次运行这整个过程几次,平均运行时间可能与上一次运行相差甚远:
0,00043149 +- 0,00000688 seconds time elapsed ( +- 1,59% )
0,00043222 +- 0,00000657 seconds time elapsed ( +- 1,52% )
0,00041690 +- 0,00000612 seconds time elapsed ( +- 1,47% )
0,00045048 +- 0,00000832 seconds time elapsed ( +- 1,85% )
0,0005051 +- 0,0000232 seconds time elapsed ( +- 4,60% )
0,00043595 +- 0,00000676 seconds time elapsed ( +- 1,55% )
0,0004271 +- 0,0000168 seconds time elapsed ( +- 3,94% )
0,00043166 +- 0,00000604 seconds time elapsed ( +- 1,40% )
0,0010521 +- 0,0000548 seconds time elapsed ( +- 5,21% )
0,00042799 +- 0,00000714 seconds time elapsed ( +- 1,67% )
这里平均值的相对偏差为 37%,主要是由倒数第二个异常值引起的。但即使我不考虑那次运行,它仍然是 5.5%,比“单次”运行的偏差大得多。
那么这里发生了什么?为什么平均不起作用(在这种情况下)?我应该做什么?
编辑:当频率缩放被禁用时也会发生这种情况(sudo cpupower frequency-set --governor performance
),但异常值似乎不太频繁。