JayBeams  0.1
Another project to have fun coding.
bm_clocks.cpp
Go to the documentation of this file.
3 
4 #include <chrono>
5 #include <iostream>
6 #include <stdexcept>
7 #include <string>
8 
9 /**
10  * Convenience types and functions for benchmarking std::chrono clocks.
11  */
12 namespace {
15 } // anonymous namespace
16 
17 int main(int argc, char* argv[]) {
18  auto testcases = create_testcases();
19  return jb::testing::microbenchmark_group_main(argc, argv, testcases);
20 }
21 
22 namespace {
23 /**
24  * @namespace defaults
25  *
26  * Define defaults for program parameters.
27  */
28 namespace defaults {
29 
30 #ifndef JB_DEFAULTS_clock_repetitions
31 #define JB_DEFAULTS_clock_repetitions 1000
32 #endif // JB_DEFAULTS_clock_repetitions
33 
34 int clock_repetitions = JB_DEFAULTS_clock_repetitions;
35 } // namespace defaults
36 
37 /**
38  * The fixture tested by the microbenchmark.
39  *
40  * @tparam clock_type the type of clock tested
41  */
42 template <typename clock_type>
43 class fixture {
44 public:
45  fixture()
46  : fixture(defaults::clock_repetitions) {
47  }
48 
49  explicit fixture(int size)
50  : calls_per_iteration_(size) {
51  }
52 
53  int run() {
54  for (int i = 0; i != calls_per_iteration_; ++i) {
55  (void)clock_type::now();
56  }
57  return calls_per_iteration_;
58  }
59 
60 private:
61  int calls_per_iteration_;
62 };
63 
64 /// Fake a std::chrono clock using rdtscp
65 struct wrapped_rtdscp {
66  static std::uint64_t now() {
67  std::uint64_t hi, lo;
68  std::uint32_t aux;
69  __asm__ __volatile__("rdtscp\n" : "=a"(lo), "=d"(hi), "=c"(aux) : :);
70  return (hi << 32) + lo;
71  }
72 };
73 
74 /// Fake a std::chrono clock using rdtsc
75 struct wrapped_rtdsc {
76  static std::uint64_t now() {
77  std::uint64_t hi, lo;
78  std::uint32_t aux;
79  __asm__ __volatile__("rdtsc\n" : "=a"(lo), "=d"(hi), "=c"(aux) : :);
80  return (hi << 32) + lo;
81  }
82 };
83 
84 template <typename clock_type>
85 std::function<void(config const&)> test_case() {
86  return [](config const& cfg) {
88  benchmark bm(cfg);
89  auto r = bm.run();
90  bm.typical_output(r);
91  };
92 }
93 
95  using namespace std::chrono;
97  {"std::chrono::steady_clock", test_case<steady_clock>()},
98  {"std::chrono::high_resolution_clock",
99  test_case<high_resolution_clock>()},
100  {"std::chrono::system_clock_clock", test_case<system_clock>()},
101  {"rdtscp", test_case<wrapped_rtdscp>()},
102  {"rdtsc", test_case<wrapped_rtdsc>()},
103  };
104 }
105 
106 } // anonymous namespace
Define defaults for program parameters.
int microbenchmark_group_main(int argc, char *argv[], microbenchmark_group< microbenchmark_config > const &testcases)
Overload microbenchmark_group_main for jb::testing::microbenchmark_config.
std::map< std::string, std::function< void(config const &cfg)> > microbenchmark_group
Define a representation for a group of microbenchmarks.
int main(int argc, char *argv[])
Definition: bm_clocks.cpp:17
Run a micro-benchmark on a given class.
#define JB_DEFAULTS_clock_repetitions
Definition: bm_clocks.cpp:31