brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 6c3cc2e Raw
158 lines · plain
1#include <atomic>2#include <cassert>3#include <cstdlib>4#include <cstring>5#include <iostream>6#include <limits>7#include <string>8 9#include "benchmark/benchmark.h"10 11// Test that Setup() and Teardown() are called exactly once12// for each benchmark run (single-threaded).13namespace singlethreaded {14static int setup_call = 0;15static int teardown_call = 0;16}  // namespace singlethreaded17static void DoSetup1(const benchmark::State& state) {18  ++singlethreaded::setup_call;19 20  // Setup/Teardown should never be called with any thread_idx != 0.21  assert(state.thread_index() == 0);22}23 24static void DoTeardown1(const benchmark::State& state) {25  ++singlethreaded::teardown_call;26  assert(state.thread_index() == 0);27}28 29static void BM_with_setup(benchmark::State& state) {30  for (auto s : state) {31  }32}33BENCHMARK(BM_with_setup)34    ->Arg(1)35    ->Arg(3)36    ->Arg(5)37    ->Arg(7)38    ->Iterations(100)39    ->Setup(DoSetup1)40    ->Teardown(DoTeardown1);41 42// Test that Setup() and Teardown() are called once for each group of threads.43namespace concurrent {44static std::atomic<int> setup_call(0);45static std::atomic<int> teardown_call(0);46static std::atomic<int> func_call(0);47}  // namespace concurrent48 49static void DoSetup2(const benchmark::State& state) {50  concurrent::setup_call.fetch_add(1, std::memory_order_acquire);51  assert(state.thread_index() == 0);52}53 54static void DoTeardown2(const benchmark::State& state) {55  concurrent::teardown_call.fetch_add(1, std::memory_order_acquire);56  assert(state.thread_index() == 0);57}58 59static void BM_concurrent(benchmark::State& state) {60  for (auto s : state) {61  }62  concurrent::func_call.fetch_add(1, std::memory_order_acquire);63}64 65BENCHMARK(BM_concurrent)66    ->Setup(DoSetup2)67    ->Teardown(DoTeardown2)68    ->Iterations(100)69    ->Threads(5)70    ->Threads(10)71    ->Threads(15);72 73// Testing interaction with Fixture::Setup/Teardown74namespace fixture_interaction {75int setup = 0;76int fixture_setup = 0;77}  // namespace fixture_interaction78 79#define FIXTURE_BECHMARK_NAME MyFixture80 81class FIXTURE_BECHMARK_NAME : public ::benchmark::Fixture {82 public:83  void SetUp(const ::benchmark::State&) override {84    fixture_interaction::fixture_setup++;85  }86 87  ~FIXTURE_BECHMARK_NAME() override {}88};89 90BENCHMARK_F(FIXTURE_BECHMARK_NAME, BM_WithFixture)(benchmark::State& st) {91  for (auto _ : st) {92  }93}94 95static void DoSetupWithFixture(const benchmark::State&) {96  fixture_interaction::setup++;97}98 99BENCHMARK_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);107 108// Testing repetitions.109namespace repetitions {110int setup = 0;111}112 113static void DoSetupWithRepetitions(const benchmark::State&) {114  repetitions::setup++;115}116static void BM_WithRep(benchmark::State& state) {117  for (auto _ : state) {118  }119}120 121BENCHMARK(BM_WithRep)122    ->Arg(1)123    ->Arg(3)124    ->Arg(5)125    ->Arg(7)126    ->Setup(DoSetupWithRepetitions)127    ->Iterations(100)128    ->Repetitions(4);129 130int main(int argc, char** argv) {131  benchmark::Initialize(&argc, argv);132 133  size_t ret = benchmark::RunSpecifiedBenchmarks(".");134  assert(ret > 0);135 136  // Setup/Teardown is called once for each arg group (1,3,5,7).137  assert(singlethreaded::setup_call == 4);138  assert(singlethreaded::teardown_call == 4);139 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));145 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 every time the bm routine is run.149  // The exact number is indeterministic, so we just assert that150  // it's more than setup.151  assert(fixture_interaction::fixture_setup > fixture_interaction::setup);152 153  // Setup is call once for each repetition * num_arg =  4 * 4 = 16.154  assert(repetitions::setup == 16);155 156  return 0;157}158