histogram_iteration.cpp 5.3 KB

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