我有一些并行的 Fortran90 代码,其中每个线程都需要生成相同的随机数序列。
我有一个似乎是线程不安全的随机数生成器,因为对于给定的种子,我完全无法在每次运行程序时重复相同的结果。
我(几乎)浏览了整个网络以寻找线程安全 RNG 的一些代码,但没有成功。任何人都可以向我提供(链接到)一个代码吗?
提前致谢!
我有一些并行的 Fortran90 代码,其中每个线程都需要生成相同的随机数序列。
我有一个似乎是线程不安全的随机数生成器,因为对于给定的种子,我完全无法在每次运行程序时重复相同的结果。
我(几乎)浏览了整个网络以寻找线程安全 RNG 的一些代码,但没有成功。任何人都可以向我提供(链接到)一个代码吗?
提前致谢!
Fortran90的一个很好的伪随机数生成器可以在英特尔数学核心向量统计库中找到。它们是线程安全的。另外,为什么它需要是线程安全的?如果您希望每个线程获得相同的列表,请为每个具有相同种子的线程实例化一个新的 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
并且您的每个线程都应该维护一个单独的状态向量,尽管所有线程都将使用相同的初始值。
我了解您需要每个线程来产生相同的随机数流。
MT19937是一个非常好的 Pseudo Random Generator,它可以生成可重现的数字流并且速度非常快。只需确保在产生线程之前生成种子,但在每个线程中生成一个单独的 MT 实例(使 MT 线程的实例本地化)。这样就可以保证每个 MT 都会产生相同的数字流。
SPRNG怎么样?我自己还没有尝试过。
我编写了 Mersenne Twister/MT19973 的线程安全 Fortran 90 版本。PRNG 的状态保存在派生类型 (randomNumberSequence) 中,您可以使用过程为生成器播种或获取序列中的下一个元素。
请参阅http://code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95
替代方案似乎是:
我知道,这不是一个非常令人鼓舞的清单。除此之外,我不知道如何在 FORTRAN 中实现它们中的任何一个!
这篇文章https://www.cmiss.org/openCMISS/wiki/RandomNumberGenerationWithOpenMP不仅链接到 Fortran 实现,还提到了使 PRNG 可用于线程所需的关键点。最重要的一点是:
Fortran90 版本的 Ziggurat 有几个带有“SAVE”属性的变量和数组。为了使统一的 RNG 并行化,似乎所需的更改是使这些变量数组具有每个线程的单独值(谨防错误共享)。那么当调用PRNG函数时,我们必须传递线程号,并使用对应的状态值。