Repository navigation
An implementation of generators from the MWCX family - #171
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #171 +/- ##
===========================================
+ Coverage 95.80% 96.11% +0.30%
===========================================
Files 118 127 +9
Lines 7653 8261 +608
===========================================
+ Hits 7332 7940 +608
Misses 321 321
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
mborland
left a comment
There was a problem hiding this comment.
Thank you for the contribution! This is a cool addition to the library. Once this cycles green I will merge it.
|
Thanks for the heads up! One question: I found the speed table very confusing initially, as it times a call, but different generators generate a different amount of random bits. Wouldn't it be more intuitive to report the same data, but using cycles/byte? In that way, one has a fair comparison, and it would be meaningful even if, say, you're filling an array. |
I agree the table could be improved, and I think cycles/byte would be a good way to do so. |
This PR adds four scrambled multiply-with-carry generators from "Scrambled Multiply-with-Carry Pseudorandom Number Generators", the same four that are being added to the Rust
rngsproject (rust-random/rngs#125):mwc192x: 64-bit outputs, 192 bits of state. Recommended for all purposes.mwc128x: 64-bit outputs, 128 bits of state.mwc128x32: 32-bit outputs, 128 bits of state. Recommended when 32-bit outputs are needed.mwc64x32: 32-bit outputs, 64 bits of state, for environments in which registers are scarce.These generators are really fast. They pass all tests I'm aware of (in particular, PractRand up to 32TB). The code is translated from the reference C implementations at https://github.com/vigna/MWCPRNG, and has the same speed.
AMD EPYC 9R45 (Zen 5, 4.5 GHz), reference C code, ns per 64 bits (details)
MWC192Xxoshiro256++xoroshiro128++MWC128XMT19937-64NVIDIA H100, ps per 32 bits for the whole GPU (details)
MWC64X/32MWC128X/32xoshiro128+xoshiro128++Notes:
detail/mwcx_arithmetic.hppusesunsigned __int128,_umul128(MSVC x64),__umulh(MSVC ARM64), or a portable 32-bit schoolbook multiplication (selected automatically on 32-bit targets;BOOST_RANDOM_MWCX_PORTABLE_MULforces it).discard(z)takes logarithmic time, andjump(c, e)advances by c · 2^e steps, for distances beyond 2^64 (e.g.,mwc192x::jump(1, 96)), so non-overlapping subsequences for parallel computations are easy to obtain. The arithmetic needs no wide multiplication.discard()andjump()are checked against the reference C code, also with the portable multiplication, with GCC 15.2 and Clang 21.1, C++11 and C++20, 64-bit and-m32. I could not test the MSVC paths.