线程安全的均匀随机数发生器

时间:2009-03-02 13:14:35

标签: thread-safety random fortran

我有一些并行的Fortran90代码,其中每个线程需要生成相同的随机数序列。

我有一个似乎是线程不安全的随机数生成器,因为对于给定的种子,每次运行程序时我都完全无法重复相同的结果。

我在(几乎)整个网络上寻找一些线程安全的RNG代码时没有成功。任何人都可以向我提供一个代码(链接)吗?

提前致谢!

8 个答案:

答案 0 :(得分:6)

可以在Pseudorandom number generator中找到Fortran90的Intel Math Kernel Vector Statistical Library好内容。它们是线程安全的。另外,为什么它需要线程安全?如果您希望每个线程获得相同的列表,请使用相同的种子为每个线程实例化一个新的PRNG。

答案 1 :(得分:3)

大多数可重复的随机数生成器需要某种形式的状态。没有国家,他们就无法做到接下来的事情。为了保证线程安全,你需要一种方法来自己保持状态(即,它不能是全局的)。

答案 2 :(得分:2)

当你说“需要生成相同的随机数序列”时,你的意思是

  • 每个线程需要生成与其他线程相同的数字流吗? 这意味着在剥离线程之前选择种子,然后使用相同的种子在每个线程中实例化一个线程局部PRNG。

  • 您希望能够在程序的不同运行之间重复相同的数字序列,但每个线程都会生成它自己的独立序列吗? 在这种情况下,您仍然无法共享单个PRNG,因为线程操作序列是非确定性的。因此,在启动线程之前,使用已知种子为单个PRNG播种,并使用它为线程生成初始种子。 然后您在每个线程中实例化线程本地生成器......

在每种情况下,您都应该注意Neil Butterworth对统计数据的评价:当以这种方式生成混合流时,PRNG所声称的大多数常见保证不可靠


在这两种情况下,您都需要线程本地PRNG。我不知道f90中有什么可用...但您也可以自己编写(查找Mersenne Twister,并编写一个以保存状态作为参数的例程...)。

在fortran 77中,这看起来像

      function PRNGthread (state)

      double state(statesize)

c stuff happens here which uses and manipulates the state vector...

      PRNGthread = result
      return 

并且每个线程都应该维护一个单独的状态向量,尽管所有线程都使用相同的初始值。

答案 3 :(得分:1)

我知道你需要每个线程产生相同的随机数流。

一个非常好的伪随机生成器,它将生成一个可重现的数字流,速度非常快MT19937。只需确保在产生线程之前生成种子,但在每个线程中生成一个单独的MT实例(使MT线程的实例成为本地)。这样就可以保证每个MT都能产生相同的数字流。

答案 4 :(得分:1)

SPRNG怎么样?我自己没试过。

答案 5 :(得分:1)

我编写了一个线程安全的Fortran 90版Mersenne Twister / MT19973。 PRNG的状态保存在派生类型(randomNumberSequence)中,您可以使用过程为生成器设定种子或获取序列中的下一个元素。

请参阅http://code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95

答案 6 :(得分:0)

替代方案似乎是:

  • 使用同步对象(例如 生成器种子上的互斥锁 值。不幸的是,这将是 在访问时序列化您的代码 发电机
  • 使用线程本地存储 生成器,所以每个线程都有自己的 种子 - 这可能会造成严重影响 适合您应用的问题
  • 如果您的平台支持合适的 原子操作,使用它 种子(但可能不会)

我知道,这不是一个非常令人鼓舞的名单。加上它,我不知道如何在FORTRAN中实现它们中的任何一个!

答案 7 :(得分:0)

本文https://www.cmiss.org/openCMISS/wiki/RandomNumberGenerationWithOpenMP不仅链接到Fortran实现,而且还提到了使PRNG与线程一起使用所需的关键点。最重要的一点是:

Ziggurat的Fortran90版本具有多个带有'SAVE'属性的变量和数组。为了并行化统一的RNG,似乎需要进行的更改是使这些变量数组的每个线程具有单独的值(注意错误共享)。然后,在调用PRNG函数时,我们必须传递线程号,并使用相应的状态值。