1 // Copyright 2015-2018 Hans Dembinski
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt
5 // or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #include <benchmark/benchmark.h>
8 #include <boost/histogram/accumulators/thread_safe.hpp>
9 #include <boost/histogram/axis/regular.hpp>
10 #include <boost/histogram/histogram.hpp>
11 #include <boost/histogram/make_histogram.hpp>
12 #include <chrono>
13 #include <functional>
14 #include <mutex>
15 #include <numeric>
16 #include <random>
17 #include <thread>
18 #include <vector>
19 #include "../test/throw_exception.hpp"
20
21 #include <cassert>
22 struct assert_check {
assert_checkassert_check23 assert_check() {
24 assert(false); // don't run with asserts enabled
25 }
26 } _;
27
28 using namespace boost::histogram;
29 using namespace std::chrono_literals;
30
31 using DS = dense_storage<unsigned>;
32 using DSTS = dense_storage<accumulators::thread_safe<unsigned>>;
33
NoThreads(benchmark::State & state)34 static void NoThreads(benchmark::State& state) {
35 std::default_random_engine gen(1);
36 std::uniform_real_distribution<> dis(0, 1);
37 const unsigned nbins = state.range(0);
38 auto hist = make_histogram_with(DS(), axis::regular<>(nbins, 0, 1));
39 for (auto _ : state) {
40 // simulate some work
41 for (volatile unsigned n = 0; n < state.range(1); ++n)
42 ;
43
44 hist(dis(gen));
45 }
46 }
47
48 std::mutex init;
49 static auto hist = make_histogram_with(DSTS(), axis::regular<>());
50
AtomicStorage(benchmark::State & state)51 static void AtomicStorage(benchmark::State& state) {
52 init.lock();
53 if (state.thread_index == 0) {
54 const unsigned nbins = state.range(0);
55 hist = make_histogram_with(DSTS(), axis::regular<>(nbins, 0, 1));
56 }
57 init.unlock();
58 std::default_random_engine gen(state.thread_index);
59 std::uniform_real_distribution<> dis(0, 1);
60 for (auto _ : state) {
61 // simulate some work
62 for (volatile unsigned n = 0; n < state.range(1); ++n)
63 ;
64 hist(dis(gen));
65 }
66 }
67
68 BENCHMARK(NoThreads)
69 ->UseRealTime()
70
71 ->Args({1 << 4, 0})
72 ->Args({1 << 6, 0})
73 ->Args({1 << 8, 0})
74 ->Args({1 << 10, 0})
75 ->Args({1 << 14, 0})
76 ->Args({1 << 18, 0})
77
78 ->Args({1 << 4, 5})
79 ->Args({1 << 6, 5})
80 ->Args({1 << 8, 5})
81 ->Args({1 << 10, 5})
82 ->Args({1 << 14, 5})
83 ->Args({1 << 18, 5})
84
85 ->Args({1 << 4, 10})
86 ->Args({1 << 6, 10})
87 ->Args({1 << 8, 10})
88 ->Args({1 << 10, 10})
89 ->Args({1 << 14, 10})
90 ->Args({1 << 18, 10})
91
92 ->Args({1 << 4, 50})
93 ->Args({1 << 6, 50})
94 ->Args({1 << 8, 50})
95 ->Args({1 << 10, 50})
96 ->Args({1 << 14, 50})
97 ->Args({1 << 18, 50})
98
99 ->Args({1 << 4, 100})
100 ->Args({1 << 6, 100})
101 ->Args({1 << 8, 100})
102 ->Args({1 << 10, 100})
103 ->Args({1 << 14, 100})
104 ->Args({1 << 18, 100})
105
106 ;
107
108 BENCHMARK(AtomicStorage)
109 ->UseRealTime()
110 ->Threads(1)
111 ->Threads(2)
112 ->Threads(4)
113
114 ->Args({1 << 4, 0})
115 ->Args({1 << 6, 0})
116 ->Args({1 << 8, 0})
117 ->Args({1 << 10, 0})
118 ->Args({1 << 14, 0})
119 ->Args({1 << 18, 0})
120
121 ->Args({1 << 4, 5})
122 ->Args({1 << 6, 5})
123 ->Args({1 << 8, 5})
124 ->Args({1 << 10, 5})
125 ->Args({1 << 14, 5})
126 ->Args({1 << 18, 5})
127
128 ->Args({1 << 4, 10})
129 ->Args({1 << 6, 10})
130 ->Args({1 << 8, 10})
131 ->Args({1 << 10, 10})
132 ->Args({1 << 14, 10})
133 ->Args({1 << 18, 10})
134
135 ->Args({1 << 4, 50})
136 ->Args({1 << 6, 50})
137 ->Args({1 << 8, 50})
138 ->Args({1 << 10, 50})
139 ->Args({1 << 14, 50})
140 ->Args({1 << 18, 50})
141
142 ->Args({1 << 4, 100})
143 ->Args({1 << 6, 100})
144 ->Args({1 << 8, 100})
145 ->Args({1 << 10, 100})
146 ->Args({1 << 14, 100})
147 ->Args({1 << 18, 100})
148
149 ;
150