mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 13:14:06 +00:00
generate random numbers outside benchmark loop (#195)
This commit is contained in:
parent
7e05d8ff34
commit
a1c76d2b0a
@ -41,6 +41,7 @@ if (ROOT_FOUND)
|
||||
target_include_directories(histogram_filling_root PRIVATE ${ROOT_INCLUDE_DIRS})
|
||||
target_link_libraries(histogram_filling_root
|
||||
PRIVATE ${ROOT_LIBRARIES} benchmark_main)
|
||||
target_compile_options(histogram_filling_root PRIVATE -frtti -fexceptions)
|
||||
# target_link_options(histogram_filling_root
|
||||
# PRIVATE ${ROOT_EXE_LINKER_FLAGS})
|
||||
endif()
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include "throw_exception.hpp"
|
||||
#include "../test/throw_exception.hpp"
|
||||
|
||||
using namespace boost::histogram;
|
||||
|
||||
|
42
benchmark/generator.hpp
Normal file
42
benchmark/generator.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2019 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 <array>
|
||||
#include <random>
|
||||
|
||||
using uniform = std::uniform_real_distribution<>;
|
||||
using normal = std::normal_distribution<>;
|
||||
|
||||
template <class Distribution>
|
||||
Distribution init();
|
||||
|
||||
template <>
|
||||
uniform init<uniform>() {
|
||||
return uniform{0.0, 1.0};
|
||||
}
|
||||
|
||||
template <>
|
||||
normal init<normal>() {
|
||||
return normal{0.5, 0.3};
|
||||
}
|
||||
|
||||
template <class Distribution, std::size_t N = 4096>
|
||||
struct generator {
|
||||
generator() {
|
||||
std::default_random_engine rng(1);
|
||||
auto dis = init<Distribution>();
|
||||
std::generate(buffer_, buffer_ + N, [&] { return dis(rng); });
|
||||
}
|
||||
|
||||
const double& operator()() {
|
||||
++ptr_;
|
||||
if (ptr_ == buffer_ + N) ptr_ = buffer_;
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
double buffer_[N];
|
||||
const double* ptr_ = buffer_ - 1;
|
||||
};
|
@ -6,64 +6,46 @@
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram/axis/regular.hpp>
|
||||
#include "throw_exception.hpp"
|
||||
#include <boost/histogram/storage_adaptor.hpp>
|
||||
#include <boost/histogram/unlimited_storage.hpp>
|
||||
|
||||
#include <random>
|
||||
#include "../test/throw_exception.hpp"
|
||||
#include "../test/utility_histogram.hpp"
|
||||
#include "generator.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
using namespace boost::histogram;
|
||||
using reg = axis::regular<>;
|
||||
using uniform = std::uniform_real_distribution<>;
|
||||
using normal = std::normal_distribution<>;
|
||||
|
||||
template <class Distribution>
|
||||
Distribution init();
|
||||
|
||||
template <>
|
||||
uniform init<uniform>() {
|
||||
return uniform{0.0, 1.0};
|
||||
}
|
||||
|
||||
template <>
|
||||
normal init<normal>() {
|
||||
return normal{0.5, 0.3};
|
||||
}
|
||||
|
||||
template <class Tag, class Storage, class Distribution>
|
||||
static void fill_1d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(dis(gen)));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(gen()));
|
||||
}
|
||||
|
||||
template <class Tag, class Storage, class Distribution>
|
||||
static void fill_2d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(100, 0, 1), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(dis(gen), dis(gen)));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(gen(), gen()));
|
||||
}
|
||||
|
||||
template <class Tag, class Storage, class Distribution>
|
||||
static void fill_3d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(100, 0, 1), reg(100, 0, 1), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(dis(gen), dis(gen), dis(gen)));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(gen(), gen(), gen()));
|
||||
}
|
||||
|
||||
template <class Tag, class Storage, class Distribution>
|
||||
static void fill_6d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(10, 0, 1), reg(10, 0, 1), reg(10, 0, 1),
|
||||
reg(10, 0, 1), reg(10, 0, 1), reg(10, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(
|
||||
h(dis(gen), dis(gen), dis(gen), dis(gen), dis(gen), dis(gen)));
|
||||
benchmark::DoNotOptimize(h(gen(), gen(), gen(), gen(), gen(), gen()));
|
||||
}
|
||||
|
||||
using SStore = std::vector<int>;
|
||||
|
@ -8,20 +8,18 @@
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/histogram/axis/traits.hpp>
|
||||
#include <boost/histogram/detail/axes.hpp>
|
||||
#include "throw_exception.hpp"
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <random>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include "../test/throw_exception.hpp"
|
||||
#include "generator.hpp"
|
||||
|
||||
using namespace boost::histogram;
|
||||
using reg = axis::regular<>;
|
||||
using integ = axis::integer<>;
|
||||
using var = axis::variable<>;
|
||||
using vector_of_variant = std::vector<axis::variant<reg, integ, var>>;
|
||||
using uniform = std::uniform_real_distribution<>;
|
||||
using normal = std::normal_distribution<>;
|
||||
|
||||
template <class T, class U>
|
||||
auto make_storage(const U& axes) {
|
||||
@ -64,27 +62,13 @@ void fill_c(const Axes& axes, const std::size_t* strides, Storage& storage,
|
||||
++storage[index];
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
Distribution init();
|
||||
|
||||
template <>
|
||||
uniform init<uniform>() {
|
||||
return uniform{0.0, 1.0};
|
||||
}
|
||||
|
||||
template <>
|
||||
normal init<normal>() {
|
||||
return normal{0.5, 0.3};
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_1d_a(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
for (auto _ : state) {
|
||||
const auto i = std::get<0>(axes).index(dis(gen));
|
||||
const auto i = std::get<0>(axes).index(gen());
|
||||
++storage[i + 1];
|
||||
}
|
||||
}
|
||||
@ -92,45 +76,41 @@ static void fill_1d_a(benchmark::State& state) {
|
||||
template <class T, class Distribution>
|
||||
static void fill_1d_b(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
for (auto _ : state) { fill_b(axes, storage, std::forward_as_tuple(dis(gen))); }
|
||||
for (auto _ : state) { fill_b(axes, storage, std::forward_as_tuple(gen())); }
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_1d_c(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
auto strides = make_strides(axes);
|
||||
for (auto _ : state) {
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(dis(gen)));
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_1d_c_dyn(benchmark::State& state) {
|
||||
auto axes = vector_of_variant({reg(100, 0, 1)});
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
auto strides = make_strides(axes);
|
||||
for (auto _ : state) {
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(dis(gen)));
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_2d_a(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
for (auto _ : state) {
|
||||
const auto i0 = std::get<0>(axes).index(dis(gen));
|
||||
const auto i1 = std::get<1>(axes).index(dis(gen));
|
||||
const auto i0 = std::get<0>(axes).index(gen());
|
||||
const auto i1 = std::get<1>(axes).index(gen());
|
||||
const auto stride = axis::traits::extent(std::get<0>(axes));
|
||||
++storage[(i0 + 1) * stride + (i1 + 1)];
|
||||
}
|
||||
@ -139,41 +119,36 @@ static void fill_2d_a(benchmark::State& state) {
|
||||
template <class T, class Distribution>
|
||||
static void fill_2d_b(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
for (auto _ : state) {
|
||||
fill_b(axes, storage, std::forward_as_tuple(dis(gen), dis(gen)));
|
||||
}
|
||||
for (auto _ : state) { fill_b(axes, storage, std::forward_as_tuple(gen(), gen())); }
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_2d_c(benchmark::State& state) {
|
||||
auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
auto strides = make_strides(axes);
|
||||
assert(strides.size() == 3);
|
||||
assert(strides[0] == 1);
|
||||
assert(strides[1] == 102);
|
||||
for (auto _ : state) {
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(dis(gen), dis(gen)));
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen(), gen()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Distribution>
|
||||
static void fill_2d_c_dyn(benchmark::State& state) {
|
||||
auto axes = vector_of_variant({reg(100, 0, 1), reg(100, 0, 1)});
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
auto storage = make_storage<T>(axes);
|
||||
auto strides = make_strides(axes);
|
||||
assert(strides.size() == 3);
|
||||
assert(strides[0] == 1);
|
||||
assert(strides[1] == 102);
|
||||
for (auto _ : state) {
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(dis(gen), dis(gen)));
|
||||
fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen(), gen()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,36 +5,17 @@
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <random>
|
||||
|
||||
#include "throw_exception.hpp"
|
||||
|
||||
#include <gsl/gsl_histogram.h>
|
||||
#include <gsl/gsl_histogram2d.h>
|
||||
|
||||
using uniform = std::uniform_real_distribution<>;
|
||||
using normal = std::normal_distribution<>;
|
||||
|
||||
template <class Distribution>
|
||||
Distribution init();
|
||||
|
||||
template <>
|
||||
uniform init<uniform>() {
|
||||
return uniform{0.0, 1.0};
|
||||
}
|
||||
|
||||
template <>
|
||||
normal init<normal>() {
|
||||
return normal{0.5, 0.3};
|
||||
}
|
||||
#include "../test/throw_exception.hpp"
|
||||
#include "generator.hpp"
|
||||
|
||||
template <class Distribution>
|
||||
static void fill_1d(benchmark::State& state) {
|
||||
gsl_histogram* h = gsl_histogram_alloc(100);
|
||||
gsl_histogram_set_ranges_uniform(h, 0, 1);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(gsl_histogram_increment(h, dis(gen)));
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state) benchmark::DoNotOptimize(gsl_histogram_increment(h, gen()));
|
||||
gsl_histogram_free(h);
|
||||
}
|
||||
|
||||
@ -42,10 +23,9 @@ template <class Distribution>
|
||||
static void fill_2d(benchmark::State& state) {
|
||||
gsl_histogram2d* h = gsl_histogram2d_alloc(100, 100);
|
||||
gsl_histogram2d_set_ranges_uniform(h, 0, 1, 0, 1);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state)
|
||||
benchmark::DoNotOptimize(gsl_histogram2d_increment(h, dis(gen), dis(gen)));
|
||||
benchmark::DoNotOptimize(gsl_histogram2d_increment(h, gen(), gen()));
|
||||
gsl_histogram2d_free(h);
|
||||
}
|
||||
|
||||
|
@ -4,52 +4,32 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <random>
|
||||
|
||||
#include <TH1I.h>
|
||||
#include <TH2I.h>
|
||||
#include <TH3I.h>
|
||||
#include <THn.h>
|
||||
|
||||
using uniform = std::uniform_real_distribution<>;
|
||||
using normal = std::normal_distribution<>;
|
||||
|
||||
template <class Distribution>
|
||||
Distribution init();
|
||||
|
||||
template <>
|
||||
uniform init<uniform>() {
|
||||
return uniform{0.0, 1.0};
|
||||
}
|
||||
|
||||
template <>
|
||||
normal init<normal>() {
|
||||
return normal{0.5, 0.3};
|
||||
}
|
||||
#include <benchmark/benchmark.h>
|
||||
#include "generator.hpp"
|
||||
|
||||
template <class Distribution>
|
||||
static void fill_1d(benchmark::State& state) {
|
||||
TH1I h("", "", 100, 0, 1);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(dis(gen)));
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(gen()));
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
static void fill_2d(benchmark::State& state) {
|
||||
TH2I h("", "", 100, 0, 1, 100, 0, 1);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(dis(gen), dis(gen)));
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(gen(), gen()));
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
static void fill_3d(benchmark::State& state) {
|
||||
TH3I h("", "", 100, 0, 1, 100, 0, 1, 100, 0, 1);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(dis(gen), dis(gen), dis(gen)));
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h.Fill(gen(), gen(), gen()));
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
@ -58,10 +38,9 @@ static void fill_6d(benchmark::State& state) {
|
||||
double min[] = {0, 0, 0, 0, 0, 0};
|
||||
double max[] = {1, 1, 1, 1, 1, 1};
|
||||
THnI h("", "", 6, bin, min, max);
|
||||
std::default_random_engine gen(1);
|
||||
Distribution dis = init<Distribution>();
|
||||
generator<Distribution> gen;
|
||||
for (auto _ : state) {
|
||||
const double buf[6] = {dis(gen), dis(gen), dis(gen), dis(gen), dis(gen), dis(gen)};
|
||||
const double buf[6] = {gen(), gen(), gen(), gen(), gen(), gen()};
|
||||
benchmark::DoNotOptimize(h.Fill(buf));
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,13 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram/axis/integer.hpp>
|
||||
#include <boost/histogram/axis/regular.hpp>
|
||||
#include "throw_exception.hpp"
|
||||
#include <boost/histogram/histogram.hpp>
|
||||
#include <boost/histogram/indexed.hpp>
|
||||
#include <boost/histogram/literals.hpp>
|
||||
#include <boost/histogram/make_histogram.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <vector>
|
||||
#include "../test/throw_exception.hpp"
|
||||
|
||||
using namespace boost::histogram;
|
||||
using namespace boost::histogram::literals;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <boost/histogram/accumulators/thread_safe.hpp>
|
||||
#include <boost/histogram/axis/regular.hpp>
|
||||
#include "throw_exception.hpp"
|
||||
#include <boost/histogram/histogram.hpp>
|
||||
#include <boost/histogram/make_histogram.hpp>
|
||||
#include <chrono>
|
||||
@ -17,6 +16,7 @@
|
||||
#include <random>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "../test/throw_exception.hpp"
|
||||
|
||||
using namespace boost::histogram;
|
||||
using namespace std::chrono_literals;
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2019 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)
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
#include <cstdlib> // std::abort
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace boost {
|
||||
// dummy implementation for user-defined function from boost/throw_exception.hpp
|
||||
inline void throw_exception(std::exception const& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user