| |
| #include "benchmark/benchmark.h" |
| |
| #define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192) |
| |
| void BM_empty(benchmark::State& state) { |
| for (auto _ : state) { |
| auto iterations = double(state.iterations()) * double(state.iterations()); |
| benchmark::DoNotOptimize(iterations); |
| } |
| } |
| BENCHMARK(BM_empty); |
| BENCHMARK(BM_empty)->ThreadPerCpu(); |
| |
| void BM_spin_empty(benchmark::State& state) { |
| for (auto _ : state) { |
| for (auto 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 (auto i = 0; i < state.range(0); ++i) { |
| benchmark::DoNotOptimize(i); |
| } |
| for (auto _ : state) { |
| for (auto 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) { |
| for (auto _ : state) { |
| state.PauseTiming(); |
| for (auto i = 0; i < state.range(0); ++i) { |
| benchmark::DoNotOptimize(i); |
| } |
| state.ResumeTiming(); |
| for (auto 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) { |
| for (auto _ : state) { |
| 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) { |
| for (auto _ : state) { |
| for (auto i = 0; i < state.range(0); ++i) { |
| benchmark::DoNotOptimize(i); |
| } |
| } |
| for (auto 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 (auto i = 0; i < state.range(0); ++i) { |
| benchmark::DoNotOptimize(i); |
| } |
| for (auto _ : state) { |
| for (auto i = 0; i < state.range(0); ++i) { |
| benchmark::DoNotOptimize(i); |
| } |
| } |
| for (auto 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) { |
| for (auto _ : state) { |
| } |
| } |
| BENCHMARK(BM_empty_stop_start); |
| BENCHMARK(BM_empty_stop_start)->ThreadPerCpu(); |
| |
| void BM_KeepRunning(benchmark::State& state) { |
| benchmark::IterationCount iter_count = 0; |
| assert(iter_count == state.iterations()); |
| while (state.KeepRunning()) { |
| ++iter_count; |
| } |
| assert(iter_count == state.iterations()); |
| } |
| BENCHMARK(BM_KeepRunning); |
| |
| void BM_KeepRunningBatch(benchmark::State& state) { |
| // Choose a batch size >1000 to skip the typical runs with iteration |
| // targets of 10, 100 and 1000. If these are not actually skipped the |
| // bug would be detectable as consecutive runs with the same iteration |
| // count. Below we assert that this does not happen. |
| const benchmark::IterationCount batch_size = 1009; |
| |
| static benchmark::IterationCount prior_iter_count = 0; |
| benchmark::IterationCount iter_count = 0; |
| while (state.KeepRunningBatch(batch_size)) { |
| iter_count += batch_size; |
| } |
| assert(state.iterations() == iter_count); |
| |
| // Verify that the iteration count always increases across runs (see |
| // comment above). |
| assert(iter_count == batch_size // max_iterations == 1 |
| || iter_count > prior_iter_count); // max_iterations > batch_size |
| prior_iter_count = iter_count; |
| } |
| // Register with a fixed repetition count to establish the invariant that |
| // the iteration count should always change across runs. This overrides |
| // the --benchmark_repetitions command line flag, which would otherwise |
| // cause this test to fail if set > 1. |
| BENCHMARK(BM_KeepRunningBatch)->Repetitions(1); |
| |
| void BM_RangedFor(benchmark::State& state) { |
| benchmark::IterationCount iter_count = 0; |
| for (auto _ : state) { |
| ++iter_count; |
| } |
| assert(iter_count == state.max_iterations); |
| } |
| BENCHMARK(BM_RangedFor); |
| |
| #ifdef BENCHMARK_HAS_CXX11 |
| template <typename T> |
| void BM_OneTemplateFunc(benchmark::State& state) { |
| auto arg = state.range(0); |
| T sum = 0; |
| for (auto _ : state) { |
| sum += static_cast<T>(arg); |
| } |
| } |
| BENCHMARK(BM_OneTemplateFunc<int>)->Arg(1); |
| BENCHMARK(BM_OneTemplateFunc<double>)->Arg(1); |
| |
| template <typename A, typename B> |
| void BM_TwoTemplateFunc(benchmark::State& state) { |
| auto arg = state.range(0); |
| A sum = 0; |
| B prod = 1; |
| for (auto _ : state) { |
| sum += static_cast<A>(arg); |
| prod *= static_cast<B>(arg); |
| } |
| } |
| BENCHMARK(BM_TwoTemplateFunc<int, double>)->Arg(1); |
| BENCHMARK(BM_TwoTemplateFunc<double, int>)->Arg(1); |
| |
| #endif // BENCHMARK_HAS_CXX11 |
| |
| // Ensure that StateIterator provides all the necessary typedefs required to |
| // instantiate std::iterator_traits. |
| static_assert( |
| std::is_same<typename std::iterator_traits< |
| benchmark::State::StateIterator>::value_type, |
| typename benchmark::State::StateIterator::value_type>::value, |
| ""); |
| |
| BENCHMARK_MAIN(); |