What is the fast modulo replacement for random number generation?
Currently I'm using a very fast XorShift algorithm:
inline uint r() {
static uint y = 2463534242u; // seed
y ^= (y<<13);
y ^= (y>>17);
y ^= (y<<5);
return y;
}
开发者_如何学Go
Now I want to generate an integer from interval [0, n). Of course I can do this:
r() % n
But this is slow. Is there a faster way?
PS A small inequalities in probabilities of different numbers in the interval are acceptable.
If your n
is below the compiler recursion depth for templates, you can try the approach from The fastest way to generate a random permutation and let the compiler optimize the modulo with more lightweight operations.
For larger n
you can use the approach from https://arxiv.org/pdf/1805.10941.pdf , where most of the time the division operation is replaced with multiplication (plus small bitwise ops).
uint32_t NextInt(const uint32_t modulo) {
const uint32_t mask = uint32_t(-1);
uint32_t x = r();
uint64_t m = x * uint64_t(modulo);
if(m < modulo) {
final uint32_t t = uint32_t(-modulo) % modulo;
while(m < t) {
x = r();
m = x * uint64_t(modulo);
}
}
return uint32_t(m >> 32);
}
精彩评论