我有一些并行的Fortran90代码,其中每个线程需要生成相同的随机数序列。
我有一个随机数生成器似乎是线程不安全的,因为对于给定的种子,我每次运行程序时都完全无法重复相同的结果。
我(几乎)整个网络都没有成功地查找一些线程安全的RNG代码。任何人都可以向我提供一个代码(链接)吗?
提前致谢!
可以在Pseudorandom number generator找到一个很好的Qazxswpoi for Fortran90。它们是线程安全的。另外,为什么它需要线程安全?如果希望每个线程获得相同的列表,请为具有相同种子的每个线程实例化一个新的PRNG。
大多数可重复的随机数发生器需要某种形式的状态。没有国家,他们就无法做到接下来的事情。为了保证线程安全,你需要一种方法来自己保持状态(即,它不能是全局的)。
当你说“需要生成相同的随机数序列”时,你的意思是
要么
在每种情况下,你都应该注意Intel Math Kernel Vector Statistical Library对统计数据所说的内容:当以这种方式生成混合流时,PRNG所声称的大多数通常保证都不可靠。
在这两种情况下,您都需要线程本地PRNG。我不知道f90中有什么可用...但你也可以自己编写(查找Neil Butterworth,编写一个以保存状态作为参数的例程......)。
在堡垒77,这看起来像
Mersenne Twister
并且每个线程都应该保持一个单独的状态向量,尽管所有线程都使用相同的初始值。
我知道你需要每个线程产生相同的随机数流。
一个非常好的伪随机生成器,它将生成一个可重现的数字流,并且非常快,是 function PRNGthread (state)
double state(statesize)
c stuff happens here which uses and manipulates the state vector...
PRNGthread = result
return
。只需确保在产生线程之前生成种子,但在每个线程中生成一个单独的MT实例(使MT线程的实例成为本地)。这样就可以保证每个MT都能产生相同的数字流。
MT19937怎么样?我自己没试过。
我编写了一个线程安全的Fortran 90版Mersenne Twister / MT19973。 PRNG的状态保存在派生类型(randomNumberSequence)中,您可以使用过程为生成器设定种子或获取序列中的下一个元素。
替代方案似乎是:
我知道,这不是一个非常令人鼓舞的名单加上它,我不知道如何在FORTRAN中实现它们中的任何一个!
本文http://code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95不仅链接到Fortran实现,还提到了使PRNG可用于线程所需的关键点。最重要的一点是:
Fortran90版本的Ziggurat有几个变量和带有'SAVE'属性的数组。为了并行化统一的RNG,似乎所需的更改是使这些变量数组为每个线程分别设置一个值(注意错误共享)。然后当调用PRNG函数时,我们必须传递线程号,并使用相应的状态值。