Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / third-party / benchmark / test / benchmark_setup_teardown_test.cc
blobefa34e15c129b73b61ce02aac50d598c8cda6e34
1 #include <atomic>
2 #include <cassert>
3 #include <cstdlib>
4 #include <cstring>
5 #include <iostream>
6 #include <limits>
7 #include <string>
9 #include "benchmark/benchmark.h"
11 // Test that Setup() and Teardown() are called exactly once
12 // for each benchmark run (single-threaded).
13 namespace single {
14 static int setup_call = 0;
15 static int teardown_call = 0;
16 } // namespace single
17 static void DoSetup1(const benchmark::State& state) {
18 ++single::setup_call;
20 // Setup/Teardown should never be called with any thread_idx != 0.
21 assert(state.thread_index() == 0);
24 static void DoTeardown1(const benchmark::State& state) {
25 ++single::teardown_call;
26 assert(state.thread_index() == 0);
29 static void BM_with_setup(benchmark::State& state) {
30 for (auto s : state) {
33 BENCHMARK(BM_with_setup)
34 ->Arg(1)
35 ->Arg(3)
36 ->Arg(5)
37 ->Arg(7)
38 ->Iterations(100)
39 ->Setup(DoSetup1)
40 ->Teardown(DoTeardown1);
42 // Test that Setup() and Teardown() are called once for each group of threads.
43 namespace concurrent {
44 static std::atomic<int> setup_call(0);
45 static std::atomic<int> teardown_call(0);
46 static std::atomic<int> func_call(0);
47 } // namespace concurrent
49 static void DoSetup2(const benchmark::State& state) {
50 concurrent::setup_call.fetch_add(1, std::memory_order_acquire);
51 assert(state.thread_index() == 0);
54 static void DoTeardown2(const benchmark::State& state) {
55 concurrent::teardown_call.fetch_add(1, std::memory_order_acquire);
56 assert(state.thread_index() == 0);
59 static void BM_concurrent(benchmark::State& state) {
60 for (auto s : state) {
62 concurrent::func_call.fetch_add(1, std::memory_order_acquire);
65 BENCHMARK(BM_concurrent)
66 ->Setup(DoSetup2)
67 ->Teardown(DoTeardown2)
68 ->Iterations(100)
69 ->Threads(5)
70 ->Threads(10)
71 ->Threads(15);
73 // Testing interaction with Fixture::Setup/Teardown
74 namespace fixture_interaction {
75 int setup = 0;
76 int fixture_setup = 0;
77 } // namespace fixture_interaction
79 #define FIXTURE_BECHMARK_NAME MyFixture
81 class FIXTURE_BECHMARK_NAME : public ::benchmark::Fixture {
82 public:
83 void SetUp(const ::benchmark::State&) BENCHMARK_OVERRIDE {
84 fixture_interaction::fixture_setup++;
87 ~FIXTURE_BECHMARK_NAME() {}
90 BENCHMARK_F(FIXTURE_BECHMARK_NAME, BM_WithFixture)(benchmark::State& st) {
91 for (auto _ : st) {
95 static void DoSetupWithFixture(const benchmark::State&) {
96 fixture_interaction::setup++;
99 BENCHMARK_REGISTER_F(FIXTURE_BECHMARK_NAME, BM_WithFixture)
100 ->Arg(1)
101 ->Arg(3)
102 ->Arg(5)
103 ->Arg(7)
104 ->Setup(DoSetupWithFixture)
105 ->Repetitions(1)
106 ->Iterations(100);
108 // Testing repetitions.
109 namespace repetitions {
110 int setup = 0;
113 static void DoSetupWithRepetitions(const benchmark::State&) {
114 repetitions::setup++;
116 static void BM_WithRep(benchmark::State& state) {
117 for (auto _ : state) {
121 BENCHMARK(BM_WithRep)
122 ->Arg(1)
123 ->Arg(3)
124 ->Arg(5)
125 ->Arg(7)
126 ->Setup(DoSetupWithRepetitions)
127 ->Iterations(100)
128 ->Repetitions(4);
130 int main(int argc, char** argv) {
131 benchmark::Initialize(&argc, argv);
133 size_t ret = benchmark::RunSpecifiedBenchmarks(".");
134 assert(ret > 0);
136 // Setup/Teardown is called once for each arg group (1,3,5,7).
137 assert(single::setup_call == 4);
138 assert(single::teardown_call == 4);
140 // 3 group of threads calling this function (3,5,10).
141 assert(concurrent::setup_call.load(std::memory_order_relaxed) == 3);
142 assert(concurrent::teardown_call.load(std::memory_order_relaxed) == 3);
143 assert((5 + 10 + 15) ==
144 concurrent::func_call.load(std::memory_order_relaxed));
146 // Setup is called 4 times, once for each arg group (1,3,5,7)
147 assert(fixture_interaction::setup == 4);
148 // Fixture::Setup is called everytime the bm routine is run.
149 // The exact number is indeterministic, so we just assert that
150 // it's more than setup.
151 assert(fixture_interaction::fixture_setup > fixture_interaction::setup);
153 // Setup is call once for each repetition * num_arg = 4 * 4 = 16.
154 assert(repetitions::setup == 16);
156 return 0;