1
0
forked from Alepha/Alepha
Files
Alepha/fastRandom.cc

72 lines
1.4 KiB
C++

static_assert( __cplusplus > 2023'00 );
#include "fastRandom.h"
#include <random>
#include <boost/random/taus88.hpp>
namespace Alepha::Hydrogen ::detail:: fastRandom_m
{
namespace
{
struct FastRandomState
{
boost::random::taus88 fastRandomState{ std::random_device{}() };
/* The choice of Taus88 is deliberate. The more familiar Mt19937
is only slightly slower and its cousin Mt11213b is effectively
no slower, but they require 100x to 200x as many integers to
maintain state. Thus with even only one random variable, the
latter two will exceed cache line size and create cache load,
but with several/many the cache pressure will be significant and
affect performance not just for this code but for the system.
*/
std::uint32_t pool;
int remainingBits= 0;
void
next()
{
pool= fastRandomState();
remainingBits= 32;
}
void
refresh()
{
if( remainingBits == 0 ) next();
}
std::uint32_t
getBit()
{
refresh();
const std::uint32_t rv= pool & 1;
--remainingBits;
pool>>= 1;
return rv;
}
std::uint32_t
get( int count )
{
std::uint32_t rv= 0;
while( count-- )
{
rv<<= 1;
rv|= getBit();
}
return rv;
}
};
thread_local FastRandomState fastRandom;
}
std::uint32_t
exports::fastRandomBits( const int numBits )
{
return fastRandom.get( numBits );
}
}