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