在使用Google Benchmark框架检查基准测试的输出时,我观察到,在许多情况下,测得的cpu时间的标准偏差明显大于测得的实时的标准偏差。
那是为什么?还是由于测量错误导致的结果? 我对此感到很惊讶,因为我希望CPU时间可以重现。
这是对我的系统的一般观察。尽管如此,我还是提供一个简单的示例:
#include <benchmark/benchmark.h>
#include <cmath>
static void BM_SineEvaluation(benchmark::State& state)
{
for (auto _ : state)
{
double y = 1.0;
for (size_t i = 0; i < 100; ++i)
{
y *= std::sin(y) * std::sin(y) + std::cos(y) * std::cos(y);
y+= std::sin(std::cos(y));
}
benchmark::DoNotOptimize(y);
}
}
BENCHMARK(BM_SineEvaluation);
该示例甚至不包含堆分配。编译器不会优化任何sin / cos函数。 这就是所有代码。时间测量完全在Google Benchmark库内部完成,该库可在github上公开使用。但是到目前为止,我还没有研究实现。
使用命令行参数--benchmark_repetitions = 50 --benchmark_report_aggregates_only = true运行程序时,我得到的输出如下:
----------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------
BM_SineEvaluation_mean 11268 ns 11270 ns 64000
BM_SineEvaluation_median 11265 ns 11230 ns 64000
BM_SineEvaluation_stddev 11 ns 90 ns 64000
我在带有(O)的Microsoft(R)C / C ++ Optimizing Compiler Version 19.00.24218.1 for x86(Visual Studio 2015)的旧版Intel Core i7 920(Bloomfield)上使用Google Benchmark v1.4.1。
编辑:我在带有gcc-8.1.1(足够聪明以-O2调用sincos的Intel i5-4300U CPU)上的Fedora-28上进行了进一步的测量,并发现了相反的行为:
----------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------
BM_SineEvaluation_mean 54642 ns 54556 ns 12350
BM_SineEvaluation_median 54305 ns 54229 ns 12350
BM_SineEvaluation_stddev 946 ns 888 ns 12350
当省略-O2时(由于它具有单独的sin / cos调用,它更接近MSVC),我仍然得到相同的定性结果:实时的标准偏差也大于cpu时间的标准偏差
我不太确定从中得出什么结论。这是否意味着Windows上的时间测量不够精确?