mirror of
https://github.com/google/benchmark.git
synced 2024-11-29 18:34:47 +00:00
0526755944
* Add C++11 Ranged For loop alternative to KeepRunning As pointed out by @astrelni and @dominichamon, the KeepRunning loop requires a bunch of memory loads and stores every iterations, which affects the measurements. The main reason for these additional loads and stores is that the State object is passed in by reference, making its contents externally visible memory, and the compiler doesn't know it hasn't been changed by non-visible code. It's also possible the large size of the State struct is hindering optimizations. This patch allows the `State` object to be iterated over using a range-based for loop. Example: void BM_Foo(benchmark::State& state) { for (auto _ : state) { [...] } } This formulation is much more efficient, because the variable counting the loop index is stored in the iterator produced by `State::begin()`, which itself is stored in function-local memory and therefore not accessible by code outside of the function. Therefore the compiler knows the iterator hasn't been changed every iteration. This initial patch and idea was from Alex Strelnikov. * Fix null pointer initialization in C++03
119 lines
3 KiB
C++
119 lines
3 KiB
C++
|
|
#include "benchmark/benchmark.h"
|
|
|
|
#define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192)
|
|
|
|
void BM_empty(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
benchmark::DoNotOptimize(state.iterations());
|
|
}
|
|
}
|
|
BENCHMARK(BM_empty);
|
|
BENCHMARK(BM_empty)->ThreadPerCpu();
|
|
|
|
void BM_spin_empty(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
for (int x = 0; x < state.range(0); ++x) {
|
|
benchmark::DoNotOptimize(x);
|
|
}
|
|
}
|
|
}
|
|
BASIC_BENCHMARK_TEST(BM_spin_empty);
|
|
BASIC_BENCHMARK_TEST(BM_spin_empty)->ThreadPerCpu();
|
|
|
|
void BM_spin_pause_before(benchmark::State& state) {
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
while (state.KeepRunning()) {
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
}
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_before);
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_before)->ThreadPerCpu();
|
|
|
|
void BM_spin_pause_during(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
state.PauseTiming();
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
state.ResumeTiming();
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
}
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_during);
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_during)->ThreadPerCpu();
|
|
|
|
void BM_pause_during(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
state.PauseTiming();
|
|
state.ResumeTiming();
|
|
}
|
|
}
|
|
BENCHMARK(BM_pause_during);
|
|
BENCHMARK(BM_pause_during)->ThreadPerCpu();
|
|
BENCHMARK(BM_pause_during)->UseRealTime();
|
|
BENCHMARK(BM_pause_during)->UseRealTime()->ThreadPerCpu();
|
|
|
|
void BM_spin_pause_after(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_after);
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_after)->ThreadPerCpu();
|
|
|
|
void BM_spin_pause_before_and_after(benchmark::State& state) {
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
while (state.KeepRunning()) {
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
for (int i = 0; i < state.range(0); ++i) {
|
|
benchmark::DoNotOptimize(i);
|
|
}
|
|
}
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after);
|
|
BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after)->ThreadPerCpu();
|
|
|
|
void BM_empty_stop_start(benchmark::State& state) {
|
|
while (state.KeepRunning()) {
|
|
}
|
|
}
|
|
BENCHMARK(BM_empty_stop_start);
|
|
BENCHMARK(BM_empty_stop_start)->ThreadPerCpu();
|
|
|
|
|
|
void BM_KeepRunning(benchmark::State& state) {
|
|
size_t iter_count = 0;
|
|
while (state.KeepRunning()) {
|
|
++iter_count;
|
|
}
|
|
assert(iter_count == state.max_iterations);
|
|
}
|
|
BENCHMARK(BM_KeepRunning);
|
|
|
|
void BM_RangedFor(benchmark::State& state) {
|
|
size_t iter_count = 0;
|
|
for (auto _ : state) {
|
|
++iter_count;
|
|
}
|
|
assert(iter_count == state.max_iterations);
|
|
}
|
|
BENCHMARK(BM_RangedFor);
|
|
|
|
BENCHMARK_MAIN()
|