• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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/axis/integer.hpp>
9 #include <boost/histogram/axis/regular.hpp>
10 #include <boost/histogram/histogram.hpp>
11 #include <boost/histogram/indexed.hpp>
12 #include <boost/histogram/literals.hpp>
13 #include <boost/histogram/make_histogram.hpp>
14 #include <boost/mp11/integral.hpp>
15 #include <vector>
16 #include "../test/throw_exception.hpp"
17 
18 #include <cassert>
19 struct assert_check {
assert_checkassert_check20   assert_check() {
21     assert(false); // don't run with asserts enabled
22   }
23 } _;
24 
25 using namespace boost::histogram;
26 using namespace boost::histogram::literals;
27 
28 struct tuple {};
29 struct vector {};
30 struct vector_of_variant {};
31 
32 template <unsigned I>
33 using Dim_t = boost::mp11::mp_int<I>;
34 
35 using d1 = Dim_t<1>;
36 using d2 = Dim_t<2>;
37 using d3 = Dim_t<3>;
38 
make_histogram(tuple,d1,unsigned n)39 auto make_histogram(tuple, d1, unsigned n) {
40   return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n));
41 }
42 
make_histogram(tuple,d2,unsigned n)43 auto make_histogram(tuple, d2, unsigned n) {
44   return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n),
45                              axis::integer<>(0, n));
46 }
47 
make_histogram(tuple,d3,unsigned n)48 auto make_histogram(tuple, d3, unsigned n) {
49   return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n),
50                              axis::integer<>(0, n), axis::integer<>(0, n));
51 }
52 
53 template <int Dim>
make_histogram(vector,boost::mp11::mp_int<Dim>,unsigned n)54 auto make_histogram(vector, boost::mp11::mp_int<Dim>, unsigned n) {
55   std::vector<axis::integer<>> axes;
56   for (unsigned d = 0; d < Dim; ++d) axes.emplace_back(axis::integer<>(0, n));
57   return make_histogram_with(std::vector<unsigned>(), std::move(axes));
58 }
59 
60 template <int Dim>
make_histogram(vector_of_variant,boost::mp11::mp_int<Dim>,unsigned n)61 auto make_histogram(vector_of_variant, boost::mp11::mp_int<Dim>, unsigned n) {
62   std::vector<axis::variant<axis::integer<>>> axes;
63   for (unsigned d = 0; d < Dim; ++d) axes.emplace_back(axis::integer<>(0, n));
64   return make_histogram_with(std::vector<unsigned>(), std::move(axes));
65 }
66 
67 template <class Tag>
Naive(benchmark::State & state,Tag,d1,coverage cov)68 static void Naive(benchmark::State& state, Tag, d1, coverage cov) {
69   auto h = make_histogram(Tag(), d1(), state.range(0));
70   const int d = cov == coverage::all;
71   for (auto _ : state) {
72     for (int i = -d; i < h.axis().size() + d; ++i) {
73       benchmark::DoNotOptimize(i);
74       benchmark::DoNotOptimize(h.at(i));
75     }
76   }
77 }
78 
79 template <class Tag>
Naive(benchmark::State & state,Tag,d2,coverage cov)80 static void Naive(benchmark::State& state, Tag, d2, coverage cov) {
81   auto h = make_histogram(Tag(), d2(), state.range(0));
82   const int d = cov == coverage::all;
83   for (auto _ : state) {
84     for (int i = -d; i < h.axis(0_c).size() + d; ++i) {
85       for (int j = -d; j < h.axis(1_c).size() + d; ++j) {
86         benchmark::DoNotOptimize(i);
87         benchmark::DoNotOptimize(j);
88         benchmark::DoNotOptimize(h.at(i, j));
89       }
90     }
91   }
92 }
93 
94 template <class Tag>
Naive(benchmark::State & state,Tag,d3,coverage cov)95 static void Naive(benchmark::State& state, Tag, d3, coverage cov) {
96   auto h = make_histogram(Tag(), d3(), state.range(0));
97   const int d = cov == coverage::all;
98   for (auto _ : state) {
99     for (int i = -d; i < h.axis(0_c).size() + d; ++i) {
100       for (int j = -d; j < h.axis(1_c).size() + d; ++j) {
101         for (int k = -d; k < h.axis(2_c).size() + d; ++k) {
102           benchmark::DoNotOptimize(i);
103           benchmark::DoNotOptimize(j);
104           benchmark::DoNotOptimize(k);
105           benchmark::DoNotOptimize(h.at(i, j, k));
106         }
107       }
108     }
109   }
110 }
111 
112 template <class Tag>
Indexed(benchmark::State & state,Tag,d1,coverage cov)113 static void Indexed(benchmark::State& state, Tag, d1, coverage cov) {
114   auto h = make_histogram(Tag(), d1(), state.range(0));
115   for (auto _ : state) {
116     for (auto&& x : indexed(h, cov)) {
117       benchmark::DoNotOptimize(*x);
118       benchmark::DoNotOptimize(x.index());
119     }
120   }
121 }
122 
123 template <class Tag>
Indexed(benchmark::State & state,Tag,d2,coverage cov)124 static void Indexed(benchmark::State& state, Tag, d2, coverage cov) {
125   auto h = make_histogram(Tag(), d2(), state.range(0));
126   for (auto _ : state) {
127     for (auto&& x : indexed(h, cov)) {
128       benchmark::DoNotOptimize(*x);
129       benchmark::DoNotOptimize(x.index(0));
130       benchmark::DoNotOptimize(x.index(1));
131     }
132   }
133 }
134 
135 template <class Tag>
Indexed(benchmark::State & state,Tag,d3,coverage cov)136 static void Indexed(benchmark::State& state, Tag, d3, coverage cov) {
137   auto h = make_histogram(Tag(), d3(), state.range(0));
138   for (auto _ : state) {
139     for (auto&& x : indexed(h, cov)) {
140       benchmark::DoNotOptimize(*x);
141       benchmark::DoNotOptimize(x.index(0));
142       benchmark::DoNotOptimize(x.index(1));
143       benchmark::DoNotOptimize(x.index(2));
144     }
145   }
146 }
147 
148 #define BENCH(Type, Tag, Dim, Cov)                                             \
149   BENCHMARK_CAPTURE(Type, (Tag, Dim, Cov), Tag{}, Dim_t<Dim>{}, coverage::Cov) \
150       ->RangeMultiplier(4)                                                     \
151       ->Range(4, 256)
152 
153 BENCH(Naive, tuple, 1, inner);
154 BENCH(Indexed, tuple, 1, inner);
155 
156 BENCH(Naive, vector, 1, inner);
157 BENCH(Indexed, vector, 1, inner);
158 
159 BENCH(Naive, vector_of_variant, 1, inner);
160 BENCH(Indexed, vector_of_variant, 1, inner);
161 
162 BENCH(Naive, tuple, 2, inner);
163 BENCH(Indexed, tuple, 2, inner);
164 
165 BENCH(Naive, vector, 2, inner);
166 BENCH(Indexed, vector, 2, inner);
167 
168 BENCH(Naive, vector_of_variant, 2, inner);
169 BENCH(Indexed, vector_of_variant, 2, inner);
170 
171 BENCH(Naive, tuple, 3, inner);
172 BENCH(Indexed, tuple, 3, inner);
173 
174 BENCH(Naive, vector, 3, inner);
175 BENCH(Indexed, vector, 3, inner);
176 
177 BENCH(Naive, vector_of_variant, 3, inner);
178 BENCH(Indexed, vector_of_variant, 3, inner);
179