mirror of
https://github.com/boostorg/histogram.git
synced 2026-02-18 02:02:10 +00:00
fixing benchmark build
This commit is contained in:
@@ -1,110 +0,0 @@
|
||||
// Copyright 2018 Hans Dembinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram/axis.hpp>
|
||||
|
||||
using namespace boost::histogram;
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void null(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i)
|
||||
volatile int j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void regular(benchmark::State& state) {
|
||||
volatile auto start = 0;
|
||||
volatile auto stop = 10;
|
||||
auto a = axis::regular<>(stop - start, start, stop);
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i) {
|
||||
volatile int j;
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void circular(benchmark::State& state) {
|
||||
volatile auto start = 0;
|
||||
volatile auto stop = 10;
|
||||
auto a = axis::circular<>(stop - start, start, stop);
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i) {
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void integer_int(benchmark::State& state) {
|
||||
volatile auto start = 0;
|
||||
volatile auto stop = 10;
|
||||
auto a = axis::integer<int>(start, stop);
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i) {
|
||||
volatile int j;
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void integer_double(benchmark::State& state) {
|
||||
volatile auto start = 0;
|
||||
volatile auto stop = 10;
|
||||
auto a = axis::integer<double>(start, stop);
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i) {
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void variable(benchmark::State& state) {
|
||||
auto a = axis::variable<>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i)
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void category(benchmark::State& state) {
|
||||
auto a = axis::category<int>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i)
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
|
||||
template <bool include_extra_bins>
|
||||
static void variant(benchmark::State& state) {
|
||||
auto a = axis::variant<axis::regular<>>(axis::regular<>(10, 0, 10));
|
||||
for (auto _ : state) {
|
||||
for (int i = 0 - include_extra_bins; i < 10 + include_extra_bins; ++i)
|
||||
benchmark::DoNotOptimize(a.index(i));
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(null, false);
|
||||
BENCHMARK_TEMPLATE(null, true);
|
||||
BENCHMARK_TEMPLATE(regular, false);
|
||||
BENCHMARK_TEMPLATE(regular, true);
|
||||
BENCHMARK_TEMPLATE(circular, false);
|
||||
BENCHMARK_TEMPLATE(circular, true);
|
||||
BENCHMARK_TEMPLATE(integer_int, false);
|
||||
BENCHMARK_TEMPLATE(integer_int, true);
|
||||
BENCHMARK_TEMPLATE(integer_double, false);
|
||||
BENCHMARK_TEMPLATE(integer_double, true);
|
||||
BENCHMARK_TEMPLATE(variable, false);
|
||||
BENCHMARK_TEMPLATE(variable, true);
|
||||
BENCHMARK_TEMPLATE(category, false);
|
||||
BENCHMARK_TEMPLATE(category, true);
|
||||
@@ -1,165 +0,0 @@
|
||||
// Copyright 2018 Hans Dembinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/mp11.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::histogram;
|
||||
using namespace boost::histogram::literals;
|
||||
|
||||
struct tuple {};
|
||||
struct vector {};
|
||||
struct vector_of_variant {};
|
||||
|
||||
template <unsigned I>
|
||||
using Dim_t = boost::mp11::mp_int<I>;
|
||||
|
||||
using d1 = Dim_t<1>;
|
||||
using d2 = Dim_t<2>;
|
||||
using d3 = Dim_t<3>;
|
||||
|
||||
auto make_histogram(tuple, d1, unsigned n) {
|
||||
return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n));
|
||||
}
|
||||
|
||||
auto make_histogram(tuple, d2, unsigned n) {
|
||||
return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n),
|
||||
axis::integer<>(0, n));
|
||||
}
|
||||
|
||||
auto make_histogram(tuple, d3, unsigned n) {
|
||||
return make_histogram_with(std::vector<unsigned>(), axis::integer<>(0, n),
|
||||
axis::integer<>(0, n), axis::integer<>(0, n));
|
||||
}
|
||||
|
||||
template <int Dim>
|
||||
auto make_histogram(vector, boost::mp11::mp_int<Dim>, unsigned n) {
|
||||
std::vector<axis::integer<>> axes;
|
||||
for (unsigned d = 0; d < Dim; ++d) axes.emplace_back(axis::integer<>(0, n));
|
||||
return make_histogram_with(std::vector<unsigned>(), std::move(axes));
|
||||
}
|
||||
|
||||
template <int Dim>
|
||||
auto make_histogram(vector_of_variant, boost::mp11::mp_int<Dim>, unsigned n) {
|
||||
std::vector<axis::variant<axis::integer<>>> axes;
|
||||
for (unsigned d = 0; d < Dim; ++d) axes.emplace_back(axis::integer<>(0, n));
|
||||
return make_histogram_with(std::vector<unsigned>(), std::move(axes));
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Naive(benchmark::State& state, Tag, d1, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d1(), state.range(0));
|
||||
const int d = cov == coverage::all;
|
||||
for (auto _ : state) {
|
||||
for (int i = -d; i < h.axis().size() + d; ++i) {
|
||||
benchmark::DoNotOptimize(i);
|
||||
benchmark::DoNotOptimize(h.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Naive(benchmark::State& state, Tag, d2, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d2(), state.range(0));
|
||||
const int d = cov == coverage::all;
|
||||
for (auto _ : state) {
|
||||
for (int i = -d; i < h.axis(0_c).size() + d; ++i) {
|
||||
for (int j = -d; j < h.axis(1_c).size() + d; ++j) {
|
||||
benchmark::DoNotOptimize(i);
|
||||
benchmark::DoNotOptimize(j);
|
||||
benchmark::DoNotOptimize(h.at(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Naive(benchmark::State& state, Tag, d3, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d3(), state.range(0));
|
||||
const int d = cov == coverage::all;
|
||||
for (auto _ : state) {
|
||||
for (int i = -d; i < h.axis(0_c).size() + d; ++i) {
|
||||
for (int j = -d; j < h.axis(1_c).size() + d; ++j) {
|
||||
for (int k = -d; k < h.axis(2_c).size() + d; ++k) {
|
||||
benchmark::DoNotOptimize(i);
|
||||
benchmark::DoNotOptimize(j);
|
||||
benchmark::DoNotOptimize(k);
|
||||
benchmark::DoNotOptimize(h.at(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Indexed(benchmark::State& state, Tag, d1, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d1(), state.range(0));
|
||||
for (auto _ : state) {
|
||||
for (auto x : indexed(h, cov)) {
|
||||
benchmark::DoNotOptimize(*x);
|
||||
benchmark::DoNotOptimize(x.index());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Indexed(benchmark::State& state, Tag, d2, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d2(), state.range(0));
|
||||
for (auto _ : state) {
|
||||
for (auto x : indexed(h, cov)) {
|
||||
benchmark::DoNotOptimize(*x);
|
||||
benchmark::DoNotOptimize(x.index(0));
|
||||
benchmark::DoNotOptimize(x.index(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void Indexed(benchmark::State& state, Tag, d3, coverage cov) {
|
||||
auto h = make_histogram(Tag(), d3(), state.range(0));
|
||||
for (auto _ : state) {
|
||||
for (auto x : indexed(h, cov)) {
|
||||
benchmark::DoNotOptimize(*x);
|
||||
benchmark::DoNotOptimize(x.index(0));
|
||||
benchmark::DoNotOptimize(x.index(1));
|
||||
benchmark::DoNotOptimize(x.index(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BENCH(Type, Tag, Dim, Cov) \
|
||||
BENCHMARK_CAPTURE(Type, (Tag, Dim, Cov), Tag{}, Dim_t<Dim>{}, coverage::Cov) \
|
||||
->RangeMultiplier(2) \
|
||||
->Range(4, 128)
|
||||
|
||||
BENCH(Naive, tuple, 1, inner);
|
||||
BENCH(Indexed, tuple, 1, inner);
|
||||
|
||||
BENCH(Naive, vector, 1, inner);
|
||||
BENCH(Indexed, vector, 1, inner);
|
||||
|
||||
BENCH(Naive, vector_of_variant, 1, inner);
|
||||
BENCH(Indexed, vector_of_variant, 1, inner);
|
||||
|
||||
BENCH(Naive, tuple, 2, inner);
|
||||
BENCH(Indexed, tuple, 2, inner);
|
||||
|
||||
BENCH(Naive, vector, 2, inner);
|
||||
BENCH(Indexed, vector, 2, inner);
|
||||
|
||||
BENCH(Naive, vector_of_variant, 2, inner);
|
||||
BENCH(Indexed, vector_of_variant, 2, inner);
|
||||
|
||||
BENCH(Naive, tuple, 3, inner);
|
||||
BENCH(Indexed, tuple, 3, inner);
|
||||
|
||||
BENCH(Naive, vector, 3, inner);
|
||||
BENCH(Indexed, vector, 3, inner);
|
||||
|
||||
BENCH(Naive, vector_of_variant, 3, inner);
|
||||
BENCH(Indexed, vector_of_variant, 3, inner);
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright 2015-2018 Hans Dembinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <atomic>
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/histogram/algorithm/sum.hpp>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace bh = boost::histogram;
|
||||
|
||||
template <typename T>
|
||||
class copyable_atomic : public std::atomic<T> {
|
||||
public:
|
||||
using std::atomic<T>::atomic;
|
||||
|
||||
// zero-initialize the atomic T
|
||||
copyable_atomic() noexcept : std::atomic<T>(T()) {}
|
||||
|
||||
// this is potentially not thread-safe, see below
|
||||
copyable_atomic(const copyable_atomic& rhs) : std::atomic<T>() { this->operator=(rhs); }
|
||||
|
||||
// this is potentially not thread-safe, see below
|
||||
copyable_atomic& operator=(const copyable_atomic& rhs) {
|
||||
if (this != &rhs) { std::atomic<T>::store(rhs.load()); }
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Histogram>
|
||||
void fill_histogram(Histogram& h, unsigned ndata) {
|
||||
using namespace std::chrono_literals;
|
||||
for (unsigned i = 0; i < ndata; ++i) {
|
||||
std::this_thread::sleep_for(10ns); // simulate some work
|
||||
h(double(i) / ndata);
|
||||
}
|
||||
}
|
||||
|
||||
static void NoThreads(benchmark::State& state) {
|
||||
auto h =
|
||||
bh::make_histogram_with(std::vector<unsigned>(), bh::axis::regular<>(100, 0, 1));
|
||||
const unsigned ndata = state.range(0);
|
||||
for (auto _ : state) {
|
||||
state.PauseTiming();
|
||||
h.reset();
|
||||
state.ResumeTiming();
|
||||
fill_histogram(h, ndata);
|
||||
state.PauseTiming();
|
||||
assert(ndata == std::accumulate(h.begin(), h.end(), 0.0));
|
||||
state.ResumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
static void AtomicStorage(benchmark::State& state) {
|
||||
auto h = bh::make_histogram_with(std::vector<copyable_atomic<unsigned>>(),
|
||||
bh::axis::regular<>(100, 0, 1));
|
||||
|
||||
const unsigned nthreads = state.range(0);
|
||||
const unsigned ndata = state.range(1);
|
||||
for (auto _ : state) {
|
||||
state.PauseTiming();
|
||||
h.reset();
|
||||
std::vector<std::thread> pool;
|
||||
pool.reserve(nthreads);
|
||||
state.ResumeTiming();
|
||||
for (unsigned i = 0; i < nthreads; ++i)
|
||||
pool.emplace_back(fill_histogram<decltype(h)>, std::ref(h), ndata / nthreads);
|
||||
for (auto&& t : pool) t.join();
|
||||
state.PauseTiming();
|
||||
assert(ndata == std::accumulate(h.begin(), h.end(), 0.0));
|
||||
state.ResumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(NoThreads)->RangeMultiplier(2)->Range(8 << 3, 8 << 5);
|
||||
BENCHMARK(AtomicStorage)->RangeMultiplier(2)->Ranges({{1, 4}, {8 << 3, 8 << 5}});
|
||||
Reference in New Issue
Block a user