我有一些并行的Fortran90代码,其中每个线程需要生成相同的随机数序列。
我有一个似乎是线程不安全的随机数生成器,因为对于给定的种子,每次运行程序时我都完全无法重复相同的结果。
我在(几乎)整个网络上寻找一些线程安全的RNG代码时没有成功。任何人都可以向我提供一个代码(链接)吗?
提前致谢!
答案 0 :(得分:6)
可以在Pseudorandom number generator中找到Fortran90的Intel Math Kernel Vector Statistical Library好内容。它们是线程安全的。另外,为什么它需要线程安全?如果您希望每个线程获得相同的列表,请使用相同的种子为每个线程实例化一个新的PRNG。
答案 1 :(得分:3)
大多数可重复的随机数生成器需要某种形式的状态。没有国家,他们就无法做到接下来的事情。为了保证线程安全,你需要一种方法来自己保持状态(即,它不能是全局的)。
答案 2 :(得分:2)
当你说“需要生成相同的随机数序列”时,你的意思是
或
在每种情况下,您都应该注意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函数时,我们必须传递线程号,并使用相应的状态值。