On Wed, May 7, 2014 at 5:36 AM, Thijs van den Berg <thijs@sitmo.com> wrote:
I did some performance test, with 4 threads -O3 and ITERATIONS = 10.000.000, and there is no performance difference between the two versions (see below). My opinion is that we should stick with a standard random engine concept I used, merge our code (we both have non-overlapping bits that are needed), and think a bit more about random function concepts at a later stage. For me a random engine is al I need.
I think my version now provides you with the 'plain old engine' concept that you're looking for. It also *allows* you to do interesting things with restart(), but you can ignore those methods if you wish.. Your version had a nice feature that mine lacked so I adoptied it: the ability to control the output type, independently of the choice of pseudo-random function. With this addition, I can produce 32-bit output from a prf that internally uses 64-bit arithmetic (or vice versa). The template is now: template<typename Prf, unsigned CtrBits = static_unsigned_min<64u, Prf::range_bits/2>::value, typename UintType = typename Prf::range_type::value_type, unsigned w = std::numeric_limits<UintType>::digits> A few examples are benchmarked at the end of the random_speed.cpp that I just pushed up to github: // An assortment of counter_based_engines with a variety of // speed/space/output-type tradeoffs: // Threefry4x64, crush-resistant with a safety margin, 64-bit // output. 248-bit seed space. 2^192 restartable sequences, each // of length 2^66. distrib(iter, "threefry4x64", boost::random::counter_based_engine<boost::random::threefry<4, uint64_t>
());
// Threefry4x64/32, crush-resistant with a safety margin, 32-bit // output. 248-bit seed space. 2^192 restartable sequences, each // of length 2^67. distrib(iter, "threefry4x64/32", boost::random::counter_based_engine<boost::random::threefry<4, uint64_t>, 64, uint32_t>()); // Philox 2x32-7 - very small (only 6x32bits of state), // crush-resistant with no safety margin. 26-bit seed space. // Reasonably fast (50-75% of mersenne), with 2^32 restart()-able // sequences each with a length of 2^33. distrib(iter, "philox2x32-7", boost::random::counter_based_engine<boost::random::philox<2, uint32_t, 7>
());
// Threefry4x64, crush-resistant but with no safety margin. 248-bit // seed space. This should be the fastest. As fast as // mersenne19937, but much smaller (13x64bits), with better or equal // quality. 2^192 restartable sequences each of length 2^67 distrib(iter, "threefry4x64-12/32", boost::random::counter_based_engine<boost::random::threefry<4, uint64_t, 12>, 64, uint32_t>());