简体   繁体   中英

Deterministic random number generator tied to instance (thread independent)

Random numbers have been well covered here, so I'll keep it brief.

I use srand and rand to generate some deterministic random numbers in a simulation. However, when running multiple simulations at once on separate threads, the individual sequence gets muddled up and becomes non deterministic, because all threads draw from the same pool. Is there an easy way to "bind" rand to draw from a specific instance? Or would I have to switch to something like Boost.Random ?

On Linux, rand_r is a reentrant version of rand , but it is a rather weak PRNG, so might want to use something from the *rand48_r family of functions.

rand_s is a reentrant version of rand on Windows, but since its state is an unsigned int, it is also bound to be quite weak.

Long story short, you're probably better off with Boost.Random.

Your compiler most likely already has something very like Boost.Random.

C++0x includes a <random> header which is based on Boost.Random (with a few tweaks here and there).

Before then, TR1, a set of "semi-standard" libraries was available for most compilers as well, which contains nearly the same <random> header.

我强烈建议使用<random><tr1/random>来细粒度访问高质量的PRNG类,您可以在每个线程中实例化一个,完全控制它们的种子,从而完成对随机数的结果序列的控制。

You can use this code, keeping a rnd_state struct for each of the threads. You may initialize the rnd_state with rand() . It's just an idea and this is a reasonable RNG.

From the linux kernel source code (random32.c)

the values in rnd_state should be initialized like: s1 > 1, s2 > 7, s3 > 15.

The paper claims this is a maximally equidistributed combined Tausworthe generator based on code from GNU Scientific Library 1.5 (30 Jun 2004)

struct rnd_state {
    u32 s1, s2, s3;
};

static u32 __random32(struct rnd_state *state)
{
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)

    state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
    state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
    state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);

    return (state->s1 ^ state->s2 ^ state->s3);
}

Academia: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps

A bunch of PRNGs are being added to the standard library. Another option is to pregenerate a large pool of numbers for each thread and then issue them one-at-a-time.

The documentation for my C++ random number library, RandomLib, contains an illustration of using parallel number streams in OpenMP; see http://randomlib.sourceforge.net/html/parallel.html . You might be able to adapt the ideas presented there to your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM