I am benchmarking some functions in our software using the Google-benchmark. Let us say the function signature is something like below. The return type can be any other derived data type.
std::map<uint32_t, bool> func(Obj& o1, Obj& o2);
The benchmark function looks something like this.
static void BM_Func(benchmark::State& state) {
// Prepare the objects o1 and o2
for (auto _ : state)
func(Obj& o1, Obj& o2);
}
BENCHMARK(BM_Func);
BENCHMARK_MAIN();
Now, the code compiles and I am able to collect the benchmark results. However, I have below questions.
benchmark::DoNotOptimize( func(Obj& o1, Obj& o2) );
to avoid optimization? I do not really understand when to call the function with benchmark::DoNotOptimize
The danger with not using benchmark::DoNotOptimize
is that the compiler might realize that func
has absolutely no side effects. It would then correctly conclude that your code is equivalent to for (auto _ : state) /* do nothing */;
. You of course didn't want to measure nothing.
Using benchmark::DoNotOptimize
prevents the compiler from the above realization. It has no choice but to actually call func
to obtain a result object (although the same considerations apply - if it can inline func
and func
always returns e.g. true
, then the rest of func
might get optimized out).
If the returned object is large, then destructing it might take a meaningful amount of time. Since this happens inside the benchmarking loop in your code, this time will be included in your benchmark. Avoiding that is pretty nontrivial though, and any "real" user of the function will have to incur this time too, so the answer is "nothing extraordinary happens with those objects".