Commit 503e84a9 authored by Christoph Conrads's avatar Christoph Conrads

Update ranlux-tools vs standard library benchmark

parent 601c9ef8
......@@ -90,7 +90,7 @@ std::string get_name(const subtract_with_borrow_engine<T, W, P, Q>&)
template<typename T, std::size_t W, std::size_t S, std::size_t R>
std::string get_name(const std::subtract_with_carry_engine<T, W, S, R>&)
{
constexpr auto FORMAT = "SWC(2^%-2zu, %1zu, %2zu)";
constexpr auto FORMAT = "SWC(2^%-2zu, %2zu, %1zu)";
char buffer[80] = { 0 };
snprintf(buffer, sizeof(buffer), FORMAT, W, S, R);
......
......@@ -10,13 +10,13 @@
// ranlux-tools subtract-with-borrow implementation with the C++11 standard
// library class `std::subtract_with_carry_engine`.
#include "benchmark.hpp"
#include <cassert>
#include <cstdio>
#include <cstdint>
#include <ctime>
#include <limits>
#include <random>
#include "random-number-engine.hpp"
#include <string>
#include <type_traits>
......@@ -24,117 +24,23 @@
namespace rlxt = ranlux_tools;
using ranlux8_base =
std::subtract_with_carry_engine<std::uint8_t, 8u, 4u, 7u>;
std::subtract_with_carry_engine<std::uint8_t, 8u, 3u, 7u>;
using ranlux16_base =
std::subtract_with_carry_engine<std::uint16_t, 16u, 3u, 11u>;
using ranlux32_base =
std::subtract_with_carry_engine<std::uint32_t, 32u, 3u, 17u>;
using ranlux64_base =
std::subtract_with_carry_engine<std::uint64_t, 64u, 4u, 26u>;
std::subtract_with_carry_engine<std::uint64_t, 64u, 7u, 13u>;
using ranlux8_swb47_base =
rlxt::subtract_with_borrow_engine<std::uint8_t, 8u, 4u, 7u>;
using ranlux8_swb58_base =
rlxt::subtract_with_borrow_engine<std::uint8_t, 8u, 5u, 8u>;
using ranlux8_swb_base =
rlxt::subtract_with_borrow_engine<std::uint8_t, 8u, 3u, 7u>;
using ranlux16_swb_base =
rlxt::subtract_with_borrow_engine<std::uint16_t, 16u, 3u, 11u>;
using ranlux32_swb_base =
rlxt::subtract_with_borrow_engine<std::uint32_t, 32u, 3u, 17u>;
#if RANLUX_TOOLS_HAS_INT128
using ranlux64_swb_base =
rlxt::subtract_with_borrow_engine<std::uint64_t, 64u, 4u, 26u>;
#endif
// do not use `clock()` because it does not work on raspberry pi
timespec get_cpu_time()
{
timespec tm = { 0, 0 };
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tm);
return tm;
}
std::uintmax_t get_time_nsec(const timespec& tm)
{
return tm.tv_nsec + std::uintmax_t{1000*1000*1000} * tm.tv_sec;
}
std::string get_name(const std::ranlux24_base&) { return "std::ranlux24_base"; }
template<typename T, std::size_t W, std::size_t P, std::size_t Q>
std::string get_name(const rlxt::subtract_with_borrow_engine<T, W, P, Q>&)
{
constexpr auto FORMAT = "RLX-SWB(2^%-2zu, %1zu, %2zu)";
char buffer[80] = { 0 };
snprintf(buffer, sizeof(buffer), FORMAT, W, P, Q);
return buffer;
}
template<typename T, std::size_t W, std::size_t S, std::size_t R>
std::string get_name(
const std::subtract_with_carry_engine<T, W, S, R>&
)
{
constexpr auto FORMAT = "STD-SWC(2^%-2zu, %1zu, %2zu)";
char buffer[80] = { 0 };
snprintf(buffer, sizeof(buffer), FORMAT, W, S, R);
return buffer;
}
template<typename Generator>
typename Generator::result_type draw(Generator& gen) __attribute__((noinline));
template<typename Generator>
typename Generator::result_type draw(Generator& gen)
{
return gen();
}
template<typename Generator>
void run(std::uintmax_t num_draws)
{
static_assert(Generator::min() == 0, "");
auto w =
Generator::max() == std::numeric_limits<std::uint64_t>::max() ? 8u :
Generator::max() == std::numeric_limits<std::uint32_t>::max() ? 4u :
Generator::max() == (1u<<24) - 1u ? 3u :
Generator::max() == std::numeric_limits<std::uint16_t>::max() ? 2u :
Generator::max() == std::numeric_limits<std::uint8_t>::max() ? 1u : 0u
;
auto gen = Generator();
auto t_0 = get_cpu_time();
for(auto i = std::uintmax_t{0}; i < num_draws; ++i)
draw(gen);
auto t_1 = get_cpu_time();
auto t_nsec = get_time_nsec(t_1) - get_time_nsec(t_0);
auto t_msec = t_nsec / (1000u*1000u);
auto bytes_per_msec = w * num_draws * 1000u / double(t_msec);
auto name = get_name(gen);
auto dummy = std::uint16_t(gen());
std::printf(
"%-25s | %10ju | %20.2e | %hu\n",
name.c_str(), t_msec, bytes_per_msec, dummy
);
}
rlxt::subtract_with_borrow_engine<std::uint64_t, 64u, 7u, 13u>;
// the c++11 standard library ranlux has only luxury level 3 meaning it discards
......@@ -148,20 +54,17 @@ int main()
constexpr auto num_draws = std::uintmax_t{1000} * 1000u * 1000u;
std::printf(
"%-25s | %10s | %20s | %s\n",
"%-25s | %10s | %20s | %s\n",
"generator", "time(sec)", "throughput(byte/sec)", "dummy"
);
run<ranlux8_base>(num_draws);
run<ranlux8_swb47_base>(num_draws);
run<ranlux8_swb58_base>(num_draws);
run<ranlux16_base>(num_draws);
run<ranlux16_swb_base>(num_draws);
run<std::ranlux24_base>(num_draws);
run<ranlux32_base>(num_draws);
run<ranlux32_swb_base>(num_draws);
#if RANLUX_TOOLS_HAS_INT128
run<ranlux64_base>(num_draws);
run<ranlux64_swb_base>(num_draws);
#endif
rlxt::run<rlxt::dummy_engine>(num_draws);
rlxt::run<ranlux8_base>(num_draws);
rlxt::run<ranlux8_swb_base>(num_draws);
rlxt::run<ranlux16_base>(num_draws);
rlxt::run<ranlux16_swb_base>(num_draws);
rlxt::run<ranlux32_base>(num_draws);
rlxt::run<ranlux32_swb_base>(num_draws);
rlxt::run<ranlux64_base>(num_draws);
rlxt::run<ranlux64_swb_base>(num_draws);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment