You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#include<vector>
#include<benchmark/benchmark.h>staticvoidbm_traverse(benchmark::State& state) {
constsize_t N = 500;
std::vector<int> vec;
for (size_t j = 0; j < N; ++j) vec.push_back(j);
for (auto _ : state) {
for (auto& value : vec) {
asm("nop"); // just to locate asm point fasterbenchmark::DoNotOptimize(value);
}
benchmark::DoNotOptimize(vec);
}
state.SetComplexityN(N);
}
BENCHMARK(bm_traverse);
BENCHMARK_MAIN();
Expected behavior
DoNotOptimize should have preserved the loop read. I understand that the reference is basically a pointer but users typically would expect that the reference represents the actual lvalue.
Screenshots
With the "&" reference in the inner loop, a vec load is not generated.
From my user point of view, DoNotOptimize() means: do something with this lvalue such that it is a noop but the compiler will still think we are using it. So if you are using the value, the DoNotOptimize() is doing its job.
That all said, this is your library so the semantics of using it is what you say. I was surprised by it. If that's known and expected then it is what it is.
Right, but still, i don't quite see it.
A reference is a pointer, while an auto is a result of dereferencing that pointer.
If you drop DoNotOptimize from either snippet, there's a lot more changes,
so DoNotOptimize did prevent the argument from being optimized away.
Describe the bug
benchmark::DoNotOptimize()
does not prevent a reference from being optimized away.System
OS: Ubuntu 20.04 LTS, Compiler explorer
Compiler: GCC 9.04, GCC trunk, Clang trunk
To reproduce
Compiler Explorer that works: https://godbolt.org/z/c3d5sc8s3
Compiler Explorer that does not: https://godbolt.org/z/3bMMvaecr
Alternatively, compile the following code
Expected behavior
DoNotOptimize should have preserved the loop read. I understand that the reference is basically a pointer but users typically would expect that the reference represents the actual lvalue.
Screenshots
With the "&" reference in the inner loop, a vec load is not generated.
If you remove the reference the vec load is generated.
Additional context
I understand this is a matter of semantics that might have been discussed in the past. In this case, I'd just like confirmation of this behavior.
The text was updated successfully, but these errors were encountered: