From 4e510da7fd6c58d6a14825f066d15d9464efeb81 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 6 Jun 2020 09:11:52 -0400 Subject: [PATCH] Performance reporting for constants (#366) * Performance reporting for constants [CI SKIP] * Remove itrunc overflow. [CI SKIP] --- .../math/constants/calculate_constants.hpp | 3 +- .../performance/constants_performance.cpp | 149 ++++++++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 reporting/performance/constants_performance.cpp diff --git a/include/boost/math/constants/calculate_constants.hpp b/include/boost/math/constants/calculate_constants.hpp index 56fcadc34..f837cbd9b 100644 --- a/include/boost/math/constants/calculate_constants.hpp +++ b/include/boost/math/constants/calculate_constants.hpp @@ -8,7 +8,7 @@ #ifndef BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED #define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED #include -#include + namespace boost{ namespace math{ namespace constants{ namespace detail{ template @@ -808,7 +808,6 @@ T zeta_series_derivative_2(unsigned digits) // Derivative of the series part, evaluated at 2: BOOST_MATH_STD_USING int n = digits * 301 * 13 / 10000; - boost::math::itrunc((std::numeric_limits::digits10 + 1) * 1.3); T d = pow(3 + sqrt(T(8)), n); d = (d + 1 / d) / 2; T b = -1; diff --git a/reporting/performance/constants_performance.cpp b/reporting/performance/constants_performance.cpp new file mode 100644 index 000000000..69a9c03b6 --- /dev/null +++ b/reporting/performance/constants_performance.cpp @@ -0,0 +1,149 @@ +// (C) Copyright Nick Thompson 2020. +// Use, modification and distribution are subject to 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 +#include +#include + +using namespace boost::math::constants; +using boost::multiprecision::mpfr_float; + +void Pi(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(pi()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Pi)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void Gauss(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(gauss()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Gauss)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void Exp1(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(e()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Exp1)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void Catalan(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(catalan()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Catalan)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void Plastic(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(plastic()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Plastic)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void RootTwo(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(root_two()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(RootTwo)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void ZetaThree(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(zeta_three()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(ZetaThree)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + + +void Euler(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(euler()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Euler)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + + +void LnTwo(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(ln_two()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(LnTwo)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond); + +void Glaisher(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(glaisher()); + } + state.SetComplexityN(state.range(0)); +} + +BENCHMARK(Glaisher)->RangeMultiplier(2)->Range(512, 4096)->Complexity()->Unit(benchmark::kMicrosecond); + + +void Khinchin(benchmark::State& state) +{ + mpfr_float::default_precision(state.range(0)); + for (auto _ : state) + { + benchmark::DoNotOptimize(khinchin()); + } + state.SetComplexityN(state.range(0)); +} + +// There is a performance bug in the Khinchin constant: +BENCHMARK(Khinchin)->RangeMultiplier(2)->Range(512, 512)->Complexity()->Unit(benchmark::kMicrosecond); + +BENCHMARK_MAIN();