В чем смысл Google Benchmark Iteration? - PullRequest
0 голосов
/ 21 октября 2019

Я работаю с 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

Но я не могне понять, в чем смысл итераций здесь? А также, почему время и процессор отличаются друг от друга?

1 Ответ

1 голос
/ 22 октября 2019

Google Benchmark пытается сравнить каждого кандидата на одинаковую сумму раз и / или достаточно долго, чтобы получить стабильные результаты.

Этот тест подсчитывает, сколько итераций он фактически выполнил,вместе с точным временем. Гораздо более медленный эталонный тест на итерацию будет выполнять гораздо меньше итераций.

Распечатка - это (рассчитанное) время на одну итерацию и (подсчитанное) итерации функции эталонного теста.

Это может быть на самом делеколичество вызовов на state.KeepRunning(), но я не знаю этого уровня детализации.


Только к вашему сведению, ваши циклы тестов не возвращают никакого результата или сохраняют его на volatile послецикл, так что компилятор может легко оптимизировать цикл. Также обратите внимание, что знаковое переполнение - это UB в C, и ваш int будет определенно переполнен.

(Или Clang все равно может оптимизировать эти циклы сумм в формулу замкнутой формы, основанную на n * (n+1) / 2 Гаусса, но избегая переполнения. )

Бенчмаркинг с отключенной оптимизацией бесполезен;не делай этого.

...