1 | |
---|---|
2 | #include "benchmark/benchmark.h" |
3 | |
4 | #define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192) |
5 | |
6 | void BM_empty(benchmark::State& state) { |
7 | for (auto _ : state) { |
8 | auto iterations = double(state.iterations()) * double(state.iterations()); |
9 | benchmark::DoNotOptimize(value&: iterations); |
10 | } |
11 | } |
12 | BENCHMARK(BM_empty); |
13 | BENCHMARK(BM_empty)->ThreadPerCpu(); |
14 | |
15 | void BM_spin_empty(benchmark::State& state) { |
16 | for (auto _ : state) { |
17 | for (auto x = 0; x < state.range(pos: 0); ++x) { |
18 | benchmark::DoNotOptimize(value&: x); |
19 | } |
20 | } |
21 | } |
22 | BASIC_BENCHMARK_TEST(BM_spin_empty); |
23 | BASIC_BENCHMARK_TEST(BM_spin_empty)->ThreadPerCpu(); |
24 | |
25 | void BM_spin_pause_before(benchmark::State& state) { |
26 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
27 | benchmark::DoNotOptimize(value&: i); |
28 | } |
29 | for (auto _ : state) { |
30 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
31 | benchmark::DoNotOptimize(value&: i); |
32 | } |
33 | } |
34 | } |
35 | BASIC_BENCHMARK_TEST(BM_spin_pause_before); |
36 | BASIC_BENCHMARK_TEST(BM_spin_pause_before)->ThreadPerCpu(); |
37 | |
38 | void BM_spin_pause_during(benchmark::State& state) { |
39 | for (auto _ : state) { |
40 | state.PauseTiming(); |
41 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
42 | benchmark::DoNotOptimize(value&: i); |
43 | } |
44 | state.ResumeTiming(); |
45 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
46 | benchmark::DoNotOptimize(value&: i); |
47 | } |
48 | } |
49 | } |
50 | BASIC_BENCHMARK_TEST(BM_spin_pause_during); |
51 | BASIC_BENCHMARK_TEST(BM_spin_pause_during)->ThreadPerCpu(); |
52 | |
53 | void BM_pause_during(benchmark::State& state) { |
54 | for (auto _ : state) { |
55 | state.PauseTiming(); |
56 | state.ResumeTiming(); |
57 | } |
58 | } |
59 | BENCHMARK(BM_pause_during); |
60 | BENCHMARK(BM_pause_during)->ThreadPerCpu(); |
61 | BENCHMARK(BM_pause_during)->UseRealTime(); |
62 | BENCHMARK(BM_pause_during)->UseRealTime()->ThreadPerCpu(); |
63 | |
64 | void BM_spin_pause_after(benchmark::State& state) { |
65 | for (auto _ : state) { |
66 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
67 | benchmark::DoNotOptimize(value&: i); |
68 | } |
69 | } |
70 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
71 | benchmark::DoNotOptimize(value&: i); |
72 | } |
73 | } |
74 | BASIC_BENCHMARK_TEST(BM_spin_pause_after); |
75 | BASIC_BENCHMARK_TEST(BM_spin_pause_after)->ThreadPerCpu(); |
76 | |
77 | void BM_spin_pause_before_and_after(benchmark::State& state) { |
78 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
79 | benchmark::DoNotOptimize(value&: i); |
80 | } |
81 | for (auto _ : state) { |
82 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
83 | benchmark::DoNotOptimize(value&: i); |
84 | } |
85 | } |
86 | for (auto i = 0; i < state.range(pos: 0); ++i) { |
87 | benchmark::DoNotOptimize(value&: i); |
88 | } |
89 | } |
90 | BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after); |
91 | BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after)->ThreadPerCpu(); |
92 | |
93 | void BM_empty_stop_start(benchmark::State& state) { |
94 | for (auto _ : state) { |
95 | } |
96 | } |
97 | BENCHMARK(BM_empty_stop_start); |
98 | BENCHMARK(BM_empty_stop_start)->ThreadPerCpu(); |
99 | |
100 | void BM_KeepRunning(benchmark::State& state) { |
101 | benchmark::IterationCount iter_count = 0; |
102 | assert(iter_count == state.iterations()); |
103 | while (state.KeepRunning()) { |
104 | ++iter_count; |
105 | } |
106 | assert(iter_count == state.iterations()); |
107 | } |
108 | BENCHMARK(BM_KeepRunning); |
109 | |
110 | void BM_KeepRunningBatch(benchmark::State& state) { |
111 | // Choose a batch size >1000 to skip the typical runs with iteration |
112 | // targets of 10, 100 and 1000. If these are not actually skipped the |
113 | // bug would be detectable as consecutive runs with the same iteration |
114 | // count. Below we assert that this does not happen. |
115 | const benchmark::IterationCount batch_size = 1009; |
116 | |
117 | static benchmark::IterationCount prior_iter_count = 0; |
118 | benchmark::IterationCount iter_count = 0; |
119 | while (state.KeepRunningBatch(n: batch_size)) { |
120 | iter_count += batch_size; |
121 | } |
122 | assert(state.iterations() == iter_count); |
123 | |
124 | // Verify that the iteration count always increases across runs (see |
125 | // comment above). |
126 | assert(iter_count == batch_size // max_iterations == 1 |
127 | || iter_count > prior_iter_count); // max_iterations > batch_size |
128 | prior_iter_count = iter_count; |
129 | } |
130 | // Register with a fixed repetition count to establish the invariant that |
131 | // the iteration count should always change across runs. This overrides |
132 | // the --benchmark_repetitions command line flag, which would otherwise |
133 | // cause this test to fail if set > 1. |
134 | BENCHMARK(BM_KeepRunningBatch)->Repetitions(n: 1); |
135 | |
136 | void BM_RangedFor(benchmark::State& state) { |
137 | benchmark::IterationCount iter_count = 0; |
138 | for (auto _ : state) { |
139 | ++iter_count; |
140 | } |
141 | assert(iter_count == state.max_iterations); |
142 | } |
143 | BENCHMARK(BM_RangedFor); |
144 | |
145 | #ifdef BENCHMARK_HAS_CXX11 |
146 | template <typename T> |
147 | void BM_OneTemplateFunc(benchmark::State& state) { |
148 | auto arg = state.range(pos: 0); |
149 | T sum = 0; |
150 | for (auto _ : state) { |
151 | sum += static_cast<T>(arg); |
152 | } |
153 | } |
154 | BENCHMARK(BM_OneTemplateFunc<int>)->Arg(x: 1); |
155 | BENCHMARK(BM_OneTemplateFunc<double>)->Arg(x: 1); |
156 | |
157 | template <typename A, typename B> |
158 | void BM_TwoTemplateFunc(benchmark::State& state) { |
159 | auto arg = state.range(pos: 0); |
160 | A sum = 0; |
161 | B prod = 1; |
162 | for (auto _ : state) { |
163 | sum += static_cast<A>(arg); |
164 | prod *= static_cast<B>(arg); |
165 | } |
166 | } |
167 | BENCHMARK(BM_TwoTemplateFunc<int, double>)->Arg(x: 1); |
168 | BENCHMARK(BM_TwoTemplateFunc<double, int>)->Arg(x: 1); |
169 | |
170 | #endif // BENCHMARK_HAS_CXX11 |
171 | |
172 | // Ensure that StateIterator provides all the necessary typedefs required to |
173 | // instantiate std::iterator_traits. |
174 | static_assert( |
175 | std::is_same<typename std::iterator_traits< |
176 | benchmark::State::StateIterator>::value_type, |
177 | typename benchmark::State::StateIterator::value_type>::value, |
178 | ""); |
179 | |
180 | BENCHMARK_MAIN(); |
181 |