0

How do I seed the random generator so that I have different number sequences on different processors?

My first attempt was using the processor's rank as seed. Then I found out the hard way that srand(0) gives the same sequence as srand(1).

Currently, I'm doing this:

srand(time(NULL) + rank)

Is this an OK approach? Or is there a better way? Thanks

0x56794E
  • 20,883
  • 13
  • 42
  • 58
  • 2
    It's common to use time as a seed, any reason you can't do that? – UKMonkey Oct 05 '16 at 12:19
  • 3
    If you have C++11 or higher you should consider using the generators in [``](http://en.cppreference.com/w/cpp/header/random) – NathanOliver Oct 05 '16 at 12:20
  • Hey @UKMonkey I try using only `time(NULL)` but sometimes all procs get the same seed, which I don't want. I want each processor has its own seed EVERYTIME. – 0x56794E Oct 05 '16 at 12:21
  • This is quite complicated to do right (in non-forgiving environments). So more information is needed. Using the right tools would be a good idea. One remark: the very common MersenneTwister for example will produce very bad quality numbers if you stick to the approach above! The best approach would be to use a library which is designed for this. Another approach is sticking to an PRNG which is able to *jump* (huge amount of steps; like 2**40 for example), like PCG and others. Then you can jump according to the rank of the processor. – sascha Oct 05 '16 at 12:21
  • 1
    `std::random_device` is designed to use hardware supported non-deterministic randomness if available as seed (e.g. available on newer Intel processors). Availability can be checked using `std::random_device::entropy` – Felix Glas Oct 05 '16 at 12:22
  • Also note that `rand` is not thread safe. If you are using rand in multiple threads you could see a mushroom cloud. – NathanOliver Oct 05 '16 at 12:27
  • Another approach: use a cryptographic hash-function to preprocess the obtained seeds (from time + rank). (all these approaches mentioned should be way better than using C++11's seed_seq) – sascha Oct 05 '16 at 12:28
  • @UKMonkey Different seeds are not enough to obtain good quality random numbers! (as introduction an excerpt from wikipedia: ```Multiple Mersenne Twister instances that differ only in seed value (but not other parameters) are not generally appropriate for Monte-Carlo simulations that require independent random number generators, though there exists a method for choosing multiple sets of parameter values.```) – sascha Oct 05 '16 at 12:34
  • 1
    What's processor rank? Why don't use CPU ID? Anyway if you're using C++ then [``](http://stackoverflow.com/q/9471604/995714) is much better – phuclv Oct 05 '16 at 12:35
  • @sascha correct; with rand however, where you can't change the implementation, different seeds are the best you can do - and if you need to come up with an algorithm to generate better seeds, the generator isn't good enough. – UKMonkey Oct 05 '16 at 12:36
  • @UKMonkey Different yes, But seed=1 and seed=2 are different, but not as good as seed=1 and seed=2**18-1 (just an example; it might be actually bad depending on the RNG). Therefore improvements are possible. – sascha Oct 05 '16 at 12:40
  • C++11 support or not? – Hatted Rooster Oct 05 '16 at 12:48
  • There's lots of ways to generate seeds - one could pick up the mouse movements for a period of time and then perform some algorithm on that to generate a seed. Time is just an easy and common one. – UKMonkey Oct 05 '16 at 12:54

3 Answers3

1

Generate different seeds with rand() initalized time(NULL) and pass that seeds to your process/thread. And yes, use something different than rand().

knivil
  • 787
  • 3
  • 11
1

Calling time() in a multi-threaded environment to seed an RNG is asking for trouble. The threads could all get the same time, they could get different ones, and it's hard to control. Seed the RNG with processor rank, as you were doing initially, but either use a decent RNG that behaves well with any seed, or if you must use rand(), simply fiddle with the rank to get a slightly better seed, e.g. rank * 5 + 123;

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
0

if you are on a *nix environment make use of /dev/random or /dev/urandom as your source of entropy. On Windows, call CryptGenRandom()

Gianluca Ghettini
  • 11,129
  • 19
  • 93
  • 159