0

I have a multithreaded program where each thread calls the function erand48() to generate a random number. Each thread has its own private random seed so the seed isn't shared. However, erand48() isn't thread-safe as said in the specification.

I have tried replacing erand48() with random() which is thread-safe, but it is much much slower and performance is my first concern.

I would also specify that I do not know the number of generated values in advance, so I can't pregenerate all of the values as other blogs suggested

Would there be any alternative for erand48() as fast as it and is thread-safe?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • By the `erand48()` manual: *Notes These functions are declared obsolete by SVID 3, which states that rand(3) should be used instead.* – alx - recommends codidact May 07 '19 at 10:16
  • 1
    @CacahueteFrito There is some contention as to whether these function really are obsolete or not: https://stackoverflow.com/a/25276434/4454124 – mnistic May 07 '19 at 10:58

2 Answers2

5

However, erand48() isn't thread-safe as said in the specification.

This is wrong, erand48() was made specifically as a thread-safe version of drand48(). To quote Open Group:

By using different arguments, erand48(), nrand48() and jrand48() allow separate modules of a large program to generate several independent streams of pseudo-random numbers, that is the sequence of numbers in each stream will not depend upon how many times the routines are called to generate numbers for the other streams.

You just have to make sure to "seed" it in each thread, perhaps as explained here: https://stackoverflow.com/a/26353855/4454124.


Update: erand48() and similar functions are supposed to be thread-safe, as per POSIX, but it would appear that they are not in glibc as they do modify a global random generator state buffer. To ensure thread safety, you can use the *_r variants, which are GNU extension. The generator state buffer is passed in with these functions.

mnistic
  • 10,866
  • 2
  • 19
  • 33
  • " The above functions record global state information for the random number generator, so they are not thread-safe." [ubuntu man page](http://manpages.ubuntu.com/manpages/bionic/en/man3/drand48.3.html) Could you explain this then to me please? Cause I may be confused now – abdul rahman taleb May 07 '19 at 20:45
  • @abdulrahmantaleb Interesting... It would seem that these functions are not implemented in a thread-safe manner even though they are supposed to, at least not in glibc. See my edit, you can use `erand48_r` instead. – mnistic May 07 '19 at 23:43
1

Have you considered in line code? You don't say how good a random number generator you want. Older versions of random() isn't reckoned to be all that good by many statistical tests.

If you look up "List of random number generators" on Wikipedia, at the bottom of the list there is "Xoroshiro128+" described as "one of the fastest generators on modern 64-bit CPUs" following the links to it's Wikipedia page and thence to the Implementation section you will find several versions listed including one in C. Maybe this could be incorporated in your code with modifications to ensure that it is thread safe (no static variables)?

There is an article on thread safe code here https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/writing_reentrant_thread_safe_code.htm

And on a thread safe random number generator here https://gist.github.com/carc1n0gen/1c3fe2fa5f1312993e1d

pjaj
  • 225
  • 4
  • 12
  • I am mostly concerned about the speed here, so I don't need a really good random number generator. Any minimal one should be enough. Thanks for the links I will look more into that ! – abdul rahman taleb May 07 '19 at 20:49
  • In that case you could in-line a simple pseudo random number generator (PRNG) of the form R(n+1) = (R(n) * A +B ) mod C where R(0) is your original seed and A,B & C are chosen depending on the type of number you want, integer or float, number of bits etc. C is often a power of 2 which reduces the mod step to a simple XOR. – pjaj May 08 '19 at 01:27