【问题标题】:Thread-safe uniform random number generator线程安全的统一随机数生成器
【发布时间】:2019-02-19 01:45:22
【问题描述】:

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

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

我(几乎)浏览了整个网络以寻找线程安全 RNG 的一些代码,但没有成功。谁能给我提供一个代码(链接)?

提前致谢!

【问题讨论】:

标签: thread-safety random fortran


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      • 每个线程都需要生成一个与其他线程相同的数字流吗? 这意味着在剥离线程之前选择种子,然后在每个线程中使用相同的种子实例化线程本地 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 
      

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

      【讨论】:

        【解决方案4】:

        我了解您需要每个线程产生相同的随机数流。

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:

              替代方案似乎是:

              • 使用同步对象(例如 一个互斥体)在生成器的种子上 价值。这将不幸 在访问时序列化您的代码 发电机
              • 在 生成器,因此每个线程都有自己的 种子 - 这可能会导致统计 您的应用存在的问题
              • 如果您的平台支持合适的 原子操作,在 种子(但它可能不会)

              我知道,这不是一个非常令人鼓舞的列表。此外,我不知道如何在 FORTRAN 中实现它们!

              【讨论】:

              • 呸。 Fortran 90 的能力丝毫不逊于 C。
              • 我知道 - FORTRAN IV 是我的第一语言。我的意思是“我个人”不知道如何在现代 fortran 中实现它们。
              【解决方案8】:

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

              Ziggurat 的 Fortran90 版本有几个带有“SAVE”属性的变量和数组。为了使统一的 RNG 并行化,似乎所需的更改是使这些变量数组具有每个线程的单独值(谨防错误共享)。那么在调用PRNG函数时,我们必须传递线程号,并使用对应的状态值。

              【讨论】:

                猜你喜欢
                • 2012-02-07
                • 1970-01-01
                • 1970-01-01
                • 2020-01-31
                • 1970-01-01
                • 2017-04-20
                • 1970-01-01
                • 1970-01-01
                • 2016-11-26
                相关资源
                最近更新 更多