我有4个测试函数 - foo1(), foo2(), foo3()和foo4()。
unsigned __int64 start;
unsigned __int64 stop;
unsigned __int64 sum;
unsigned __int64 orig;
sum = 0;
for (int i = 0; i < 10000; i++)
{
start = __rdtsc();
foo1();
stop = __rdtsc();
sum += (stop - start);
}
orig=sum;
cout << "foo1() \taverage: " << (sum / 10000.0) << ", \tratio: " << ((double)orig / sum) << endl << endl;
sum = 0;
for (int i = 0; i < 10000; i++)
{
start = __rdtsc();
foo2();
stop = __rdtsc();
sum += (stop - start);
}
cout << "foo2() \taverage: " << (sum / 10000.0) << ", \tratio: " << ((double)orig / sum) << endl << endl;
以此类推,foo3()和foo4()。
我在控制台有这个日志。
foo1() average: 401495, ratio: 1
foo2() average: 24251.2, ratio: 16.5557
foo3() average: 11497.7, ratio: 34.9195
foo4() average: 7439.06, ratio: 53.9713
这是否意味着使用foo4()比foo1()快50倍(实时)?
还是说foo4()的性能肯定比foo1()好?
"更快"和"更优"在单线程、无争议的情况下是等价的,前提是测量正确。
从外观上看,50倍的加速测量是函数比基线快,从而更好的肯定标志。
BUT在你得出结论之前。
把你的代码包进另一个外循环中, 循环至少几百毫秒, 扔掉前200毫秒的结果, 然后再取下. 平均 的剩余测量值。如果被测函数访问内存,这一点尤为重要。内存缓存效应可以解释100倍以上的时间差。
添加一个调用到 _mm_lfence()
在每次 foo
的调用,以确保在进行时钟测量之前,它的所有指令都已经退场。
微基准是很难的,这往往意味着一些功能只能结合起来进行有意义的测量,同时处理的数据量也应该与现实生活中的场景大致相当。