// Copyright 2020 Matt Borland // // 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 #include #include #include #include #include #include // Individual Algos template inline auto linear_sieve_helper(Integer upper_bound, std::vector primes) -> std::vector { boost::math::detail::linear_sieve(upper_bound, primes); return primes; } template void linear_sieve(benchmark::State& state) { Integer upper = static_cast(state.range(0)); for(auto _ : state) { std::vector primes; benchmark::DoNotOptimize(linear_sieve_helper(upper, primes)); } state.SetComplexityN(state.range(0)); } template void linear_sieve_oi(benchmark::State& state) { Integer upper = static_cast(state.range(0)); std::vector primes; boost::math::prime_reserve(upper, primes); for(auto _ : state) { benchmark::DoNotOptimize(boost::math::detail::prime_sieve::linear_sieve(upper, std::back_inserter(primes))); } state.SetComplexityN(state.range(0)); } template inline auto mask_sieve_helper(Integer lower_bound, Integer upper_bound, std::vector primes) -> std::vector { boost::math::detail::mask_sieve(lower_bound, upper_bound, primes); return primes; } template void mask_sieve(benchmark::State& state) { Integer lower = static_cast(2); Integer upper = static_cast(state.range(0)); for(auto _ : state) { std::vector primes; benchmark::DoNotOptimize(mask_sieve_helper(lower, upper, primes)); } state.SetComplexityN(state.range(0)); } template inline auto interval_sieve_helper(Integer lower_bound, Integer upper_bound, std::vector primes) -> std::vector { std::vector pre_sieved_primes {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71}; boost::math::detail::IntervalSieve sieve(lower_bound, upper_bound, pre_sieved_primes, primes); return primes; } template void interval_sieve(benchmark::State& state) { Integer lower = static_cast(2); Integer upper = static_cast(state.range(0)); for(auto _ : state) { std::vector primes; benchmark::DoNotOptimize(interval_sieve_helper(lower, upper, primes)); } state.SetComplexityN(state.range(0)); } // Complete Implementations template inline auto prime_sieve_helper(ExecuitionPolicy policy, Integer upper, Container primes) { boost::math::prime_sieve(policy, upper, primes); return primes; } template void prime_sieve(benchmark::State& state) { Integer upper = static_cast(state.range(0)); for(auto _ : state) { std::vector primes; benchmark::DoNotOptimize(prime_sieve_helper(std::execution::par, upper, primes)); } state.SetComplexityN(state.range(0)); } template inline decltype(auto) prime_sieve_oi_helper(ExecutionPolicy policy, Integer upper, OutputIterator resultant_primes) { return boost::math::prime_sieve_iter(policy, upper, resultant_primes); } template void prime_sieve_oi(benchmark::State& state) { Integer upper = static_cast(state.range(0)); std::vector primes; boost::math::prime_reserve(upper, primes); for(auto _ : state) { benchmark::DoNotOptimize(prime_sieve_oi_helper(std::execution::par, upper, primes.begin())); } state.SetComplexityN(state.range(0)); } template inline auto kimwalish_primes_helper(Integer upper, std::vector primes) -> std::vector { primesieve::generate_primes(upper, &primes); return primes; } template void kimwalish_primes(benchmark::State& state) { Integer upper = static_cast(state.range(0)); for (auto _ : state) { std::vector primes; benchmark::DoNotOptimize(kimwalish_primes_helper(upper, primes)); } state.SetComplexityN(state.range(0)); } // Invidiual Implementations // Linear //BENCHMARK_TEMPLATE(linear_sieve, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity(benchmark::oN); //BENCHMARK_TEMPLATE(linear_sieve, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity(benchmark::oN); //BENCHMARK_TEMPLATE(linear_sieve, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity(benchmark::oN); // Linear output iterator //BENCHMARK_TEMPLATE(linear_sieve_oi, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity(benchmark::oN); // Segmented //BENCHMARK_TEMPLATE(mask_sieve, int32_t)->RangeMultiplier(2)->Range(1 << 2, 2 << 22)->Complexity(benchmark::oNLogN); //BENCHMARK_TEMPLATE(mask_sieve, int64_t)->RangeMultiplier(2)->Range(1 << 14, 2 << 26)->Complexity(benchmark::oNLogN); //BENCHMARK_TEMPLATE(interval_sieve, int64_t)->RangeMultiplier(2)->Range(1 << 14, 2 << 26)->Complexity(); //BENCHMARK_TEMPLATE(mask_sieve, uint32_t)->RangeMultiplier(2)->Range(1 << 2, 2 << 22)->Complexity(benchmark::oNLogN); // Complete Implemenations //BENCHMARK_TEMPLATE(prime_sieve, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); BENCHMARK_TEMPLATE(prime_sieve, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); BENCHMARK_TEMPLATE(prime_sieve_oi, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); //BENCHMARK_TEMPLATE(kimwalish_primes, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); // Benchmark //BENCHMARK_TEMPLATE(prime_sieve, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); //BENCHMARK_TEMPLATE(prime_sieve, boost::multiprecision::cpp_int)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); //BENCHMARK_TEMPLATE(prime_sieve, boost::multiprecision::mpz_int)->RangeMultiplier(2)->Range(1 << 1, 1 << 30)->Complexity(benchmark::oN)->UseRealTime(); BENCHMARK_MAIN();