mirror of
https://github.com/luxfi/intx.git
synced 2026-10-30 16:22:26 +00:00
86 lines
2.9 KiB
C++
86 lines
2.9 KiB
C++
// intx: extended precision integer library.
|
|
// Copyright 2019 Pawel Bylica.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
/// @file
|
|
/// Helpers for generating random inputs for benchmarks.
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <iterator>
|
|
#include <random>
|
|
|
|
namespace intx::test
|
|
{
|
|
using seed_type = std::random_device::result_type;
|
|
|
|
inline seed_type get_seed()
|
|
{
|
|
return 2358091149;
|
|
}
|
|
|
|
/// Linear congruential generator for any integer type.
|
|
template <typename Int>
|
|
struct lcg
|
|
{
|
|
Int state = 0;
|
|
|
|
explicit lcg(seed_type seed) : state{seed}
|
|
{
|
|
// Run for some time to fill the state.
|
|
for (int i = 0; i < 97; ++i)
|
|
(*this)();
|
|
}
|
|
|
|
Int operator()()
|
|
{
|
|
return state = static_cast<Int>(Int{0x5851f42d4c957f2d} * state + Int{0x14057b7ef767814f});
|
|
}
|
|
};
|
|
|
|
|
|
inline std::vector<uint64_t> gen_uniform_seq(size_t num)
|
|
{
|
|
std::mt19937_64 rng{get_seed()};
|
|
std::uniform_int_distribution<uint64_t> dist;
|
|
std::vector<uint64_t> seq;
|
|
std::generate_n(std::back_inserter(seq), num, [&] { return dist(rng); });
|
|
return seq;
|
|
}
|
|
|
|
/// The number of samples in samples sets.
|
|
/// The value is selected to stay in L1 cache, i.e. 32*1024 / (2 * 512 / 8) == 256.
|
|
/// However, the bigger values increase execution time only slightly, so the value
|
|
/// may be increased if that's over better samples distribution.
|
|
constexpr size_t num_samples = 256;
|
|
|
|
enum samples_set_id // NOLINT(*-use-enum-class)
|
|
{
|
|
x_64, ///< Set of random samples with ~64 (1 word) significant bits.
|
|
x_128, ///< Set of random samples with ~128 (2 words) significant bits.
|
|
x_192, ///< Set of random samples with ~192 (3 words) significant bits.
|
|
x_256, ///< Set of random samples with ~256 (4 words) significant bits.
|
|
x_256_mixed, ///< Equal combination of above 4 sets, shuffled.
|
|
y_64, ///< Set of random samples with ~64 (1 word) significant bits, different from x_64.
|
|
y_128, ///< Set of random samples with ~128 (2 words) significant bits, different from x_128.
|
|
y_192, ///< Set of random samples with ~192 (3 words) significant bits, different from x_192.
|
|
y_256, ///< Set of random samples with ~256 (4 words) significant bits, different from x_256.
|
|
y_256_mixed, ///< Equal combination of above 4 sets, shuffled exactly as x_256_mixed.
|
|
lt_256, ///< Set of random samples where each lt_256[i] <= x_256[i] && lt_256[i] <= y_256[i].
|
|
lt_x_256, ///< Set of random samples where each lt_x_256[i] <= x_256[i].
|
|
x_512, ///< Set of random samples with ~512 (8 words) significant bits.
|
|
y_512, ///< Set of random samples with ~512 (8 words) significant bits, different from x_512.
|
|
norm, ///< Set of random samples of normalized (first bit set) values.
|
|
shift_w0,
|
|
shift_w1,
|
|
shift_w2,
|
|
shift_w3,
|
|
shift_mixed,
|
|
};
|
|
|
|
template <typename T>
|
|
const std::array<T, num_samples>& get_samples(samples_set_id id) noexcept;
|
|
|
|
|
|
} // namespace intx::test
|