Почему время процессора в тестах обычно больше, чем в реальном времени?
Изучая результаты моих тестов с помощью платформы Google Benchmark, я заметил, что стандартное отклонение измеренного времени процессора во многих случаях значительно больше стандартного отклонения измеренного реального времени.
Это почему? Или это результат ошибок измерений? Я весьма удивлен этим, потому что ожидал, что время процессора будет более воспроизводимым.
Это общее наблюдение в моей системе. Тем не менее, я приведу простой пример:
#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
Я использую Google Benchmark v1.4.1 на действительно старом Intel Core i7 920 (Bloomfield) с оптимизирующим компилятором Microsoft (R) C/C++ версии 19.00.24218.1 для x86 (Visual Studio 2015) с /O2.
Изменить: Я сделал дальнейшие измерения на Fedora-28 на процессоре Intel i5-4300U с gcc-8.1.1 (который достаточно умен, чтобы вызывать sincos с -O2) и обнаружил противоречивое поведение:
----------------------------------------------------------------
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 (который ближе к MSVC, потому что он имеет отдельные вызовы sin/cos), я все же получаю тот же качественный результат: стандартное отклонение реального времени также больше стандартного отклонения времени процессора.
Я не совсем уверен, какой вывод из этого сделать. Значит ли это, что измерения времени в Windows менее точны?