Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

64 bits Seeds for random generators

I am currently running a multithreading simulation application with 8+ pipes (threads). These pipes run a very complex code that depends on a random sequence generated by a seed. The sequence is then boiled down to a single 0/1.

I want this "random processing" to be 100% deterministic after passing a seed to the processing pipe from the main thread. So, I can replicate the results in a second run.

So, for example: (I have this coded and it works)

Pipe 1 -> Seed: 123 -> Result: 0
Pipe 2 -> Seed: 123 -> Result: 0
Pipe 3 -> Seed: 589 -> Result: 1

The problem arises when I need to run 100M or more of these processes and then average the results. It may be the case only 1 of the 100M is a 1, and the rest are 0. As it is obvious, I cannot sample 100M random values with 32bit seeds feeding to srand().

Is it possible to seed with a 64bit seed in VS2010 to srand(), or use a equivalent approach?

Does rand() repeat itself after 2^32 or does not (has some inner hidden state)?

Thanks

like image 678
DarkZeros Avatar asked Feb 15 '23 19:02

DarkZeros


2 Answers

You can use C++11's random facilities to generate random numbers of a given size and seed size, though the process is a bit too complicated to summarize here.

For example, you can construct an std::mersenne_twister<uint64_t, ...> and seed it with a 64-bit integer, then acquire random numbers within a specified distribution, which seems to be what you're looking for.

like image 83
Collin Dauphinee Avatar answered Feb 28 '23 07:02

Collin Dauphinee


A simple 64-bit LCG should meet your needs. Bit n (counting from the least significant as bit 1) of an LCG has period at most (and, if parameters are chosen correctly, then exactly) 2^n, so avoid using the lower bits if you don't need them, and/or use a tempering function on the output. A sample implementation can be found in my answer to another question here:

https://stackoverflow.com/a/19083740/379897

And reposted:

static uint32_t temper(uint32_t x)
{
    x ^= x>>11;
    x ^= x<<7 & 0x9D2C5680;
    x ^= x<<15 & 0xEFC60000;
    x ^= x>>18;
    return x;
}
uint32_t lcg64_temper(uint64_t *seed)
{
    *seed = 6364136223846793005ULL * *seed + 1;
    return temper(*seed >> 32);
}
like image 33
R.. GitHub STOP HELPING ICE Avatar answered Feb 28 '23 09:02

R.. GitHub STOP HELPING ICE