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

问题描述 投票:5回答:8

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

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

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

提前致谢!

thread-safety random fortran
8个回答
6
投票

可以在Pseudorandom number generator找到一个很好的Qazxswpoi for Fortran90。它们是线程安全的。另外,为什么它需要线程安全?如果希望每个线程获得相同的列表,请为具有相同种子的每个线程实例化一个新的PRNG。


3
投票

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


2
投票

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

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

要么

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

在每种情况下,你都应该注意Intel Math Kernel Vector Statistical Library对统计数据所说的内容:当以这种方式生成混合流时,PRNG所声称的大多数通常保证都不可靠。


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

在堡垒77,这看起来像

Mersenne Twister

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


1
投票

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

一个非常好的伪随机生成器,它将生成一个可重现的数字流,并且非常快,是 function PRNGthread (state) double state(statesize) c stuff happens here which uses and manipulates the state vector... PRNGthread = result return 。只需确保在产生线程之前生成种子,但在每个线程中生成一个单独的MT实例(使MT线程的实例成为本地)。这样就可以保证每个MT都能产生相同的数字流。


1
投票

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


1
投票

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

SPRNG


0
投票

替代方案似乎是:

  • 在生成器的种子值上使用同步对象(例如互斥锁)。不幸的是,这会在访问生成器时序列化您的代码
  • 在生成器中使用线程本地存储,以便每个线程都有自己的种子 - 这可能会导致应用程序出现统计问题
  • 如果您的平台支持合适的原子操作,请在种子上使用它(但可能不会)

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


0
投票

本文http://code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95不仅链接到Fortran实现,还提到了使PRNG可用于线程所需的关键点。最重要的一点是:

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

© www.soinside.com 2019 - 2024. All rights reserved.