mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Fast prng is pcg
This commit is contained in:
@ -6,6 +6,7 @@ Version 217:
|
||||
* Fix file_body_win32
|
||||
* Use async_initiate
|
||||
* Check BOOST_NO_CXX11_THREAD_LOCAL
|
||||
* Fast prng is pcg
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
65
include/boost/beast/core/detail/pcg.hpp
Normal file
65
include/boost/beast/core/detail/pcg.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/beast
|
||||
//
|
||||
|
||||
#ifndef BOOST_BEAST_CORE_DETAIL_PCG_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_PCG_HPP
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
class pcg
|
||||
{
|
||||
std::uint64_t state_ = 0;
|
||||
std::uint64_t increment_;
|
||||
|
||||
public:
|
||||
using result_type = std::uint32_t;
|
||||
|
||||
// Initialize the generator.
|
||||
// There are no restrictions on the input values.
|
||||
pcg(
|
||||
std::uint64_t seed,
|
||||
std::uint64_t stream)
|
||||
{
|
||||
// increment must be odd
|
||||
increment_ = 2 * stream + 1;
|
||||
boost::ignore_unused((*this)());
|
||||
state_ += seed;
|
||||
boost::ignore_unused((*this)());
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
operator()()
|
||||
{
|
||||
std::uint64_t const p = state_;
|
||||
state_ = p *
|
||||
6364136223846793005ULL +
|
||||
increment_;
|
||||
std::uint32_t const x =
|
||||
static_cast<std::uint32_t>(
|
||||
((p >> 18) ^ p) >> 27);
|
||||
std::uint32_t const r = p >> 59;
|
||||
#ifdef BOOST_MSVC
|
||||
return _rotr(x, r);
|
||||
#else
|
||||
return (x >> r) | (x << ((1 + ~r) & 31));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#define BOOST_BEAST_WEBSOCKET_DETAIL_IMPL_PRNG_IPP
|
||||
|
||||
#include <boost/beast/core/detail/chacha.hpp>
|
||||
#include <boost/beast/core/detail/pcg.hpp>
|
||||
#include <boost/align/aligned_alloc.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <atomic>
|
||||
@ -119,21 +120,25 @@ make_prng_no_tls(bool secure)
|
||||
class fast_prng final : public prng
|
||||
{
|
||||
int refs_ = 0;
|
||||
std::minstd_rand r_;
|
||||
beast::detail::pcg r_;
|
||||
|
||||
public:
|
||||
fast_prng* next = nullptr;
|
||||
|
||||
fast_prng()
|
||||
: r_([]
|
||||
{
|
||||
static std::atomic<
|
||||
std::uint64_t> nonce{0};
|
||||
: r_(
|
||||
[]{
|
||||
auto const pv = prng_seed();
|
||||
return static_cast<value_type>(
|
||||
pv[0] + pv[1] + pv[2] + pv[3] +
|
||||
pv[4] + pv[5] + pv[6] + pv[7] +
|
||||
++nonce);
|
||||
return
|
||||
((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^
|
||||
((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^
|
||||
((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^
|
||||
((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]);
|
||||
}(),
|
||||
[]{
|
||||
static std::atomic<
|
||||
std::uint32_t> nonce{0};
|
||||
return ++nonce;
|
||||
}())
|
||||
{
|
||||
}
|
||||
@ -215,19 +220,23 @@ make_prng_tls(bool secure)
|
||||
{
|
||||
class fast_prng final : public prng
|
||||
{
|
||||
std::minstd_rand r_;
|
||||
beast::detail::pcg r_;
|
||||
|
||||
public:
|
||||
fast_prng()
|
||||
: r_([]
|
||||
{
|
||||
static std::atomic<
|
||||
std::uint64_t> nonce{0};
|
||||
: r_(
|
||||
[]{
|
||||
auto const pv = prng_seed();
|
||||
return static_cast<value_type>(
|
||||
pv[0] + pv[1] + pv[2] + pv[3] +
|
||||
pv[4] + pv[5] + pv[6] + pv[7] +
|
||||
++nonce);
|
||||
return
|
||||
((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^
|
||||
((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^
|
||||
((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^
|
||||
((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]);
|
||||
}(),
|
||||
[]{
|
||||
static std::atomic<
|
||||
std::uint32_t> nonce{0};
|
||||
return ++nonce;
|
||||
}())
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user