2

我正在使用 Google Benchmark 来测量一些代码的执行时间。例如,我编写了以下代码来衡量其执行时间性能。

#include <benchmark/benchmark.h>

// Alternatively, can add libraries using linker options.
#ifdef _WIN32
#pragma comment ( lib, "Shlwapi.lib" )
#ifdef _DEBUG
#pragma comment ( lib, "benchmarkd.lib" )
#else
#pragma comment ( lib, "benchmark.lib" )
#endif
#endif

static void BenchmarkTestOne(benchmark::State& state) {
    int Sum = 0;
    while (state.KeepRunning())
    {
        for (size_t i = 0; i < 100000; i++)
        {
            Sum += i;
        }
    }
}

static void BenchmarkTestTwo(benchmark::State& state) {
    int Sum = 0;
    while (state.KeepRunning())
    {
        for (size_t i = 0; i < 10000000; i++)
        {
            Sum += i;
        }
    }
}

// Register the function as a benchmark
BENCHMARK(BenchmarkTestOne);
BENCHMARK(BenchmarkTestTwo);


// Run the benchmark
BENCHMARK_MAIN();

当上面的代码运行时,它显示了以下结果:

Benchmark                 Time             CPU   Iterations
-----------------------------------------------------------
BenchmarkTestOne     271667 ns       272770 ns         2635
BenchmarkTestTwo   27130981 ns     27644231 ns           26

但我无法弄清楚这里的迭代是什么意思?还有为什么时间和CPU彼此不同?

4

1 回答 1

5

Google Benchmark 会尝试在相似的时间和/或足够长的时间内对每个候选人进行基准测试以获得稳定的结果。

基准计算它实际进行了多少次迭代,以及确切的时间。慢得多的每次迭代基准测试将执行更少的迭代。

打印输出是(计算的)每次迭代时间和(计数的)基准函数的迭代。

它实际上可能是对调用的计数state.KeepRunning(),但我不知道详细程度。


仅供参考,您的基准循环不会返回任何结果或将其存储到volatile循环之后,因此编译器可以轻松优化循环。另请注意,签名溢出是 C 中的 UB,您int肯定会溢出。

(或者 clang 仍然可以将这些求和循环优化为基于高斯的封闭形式公式,n * (n+1) / 2但避免溢出。)

禁用优化的基准测试毫无用处;不要这样做。

于 2019-10-22T01:17:07.950 回答