使用 Bays-Durham 的 L'Ecuyer 随机数生成器

Random number generator of L'Ecuyer with Bays-Durham

我正在使用 Monte Carlo 模拟来查找 PI 的小数位。到目前为止一切顺利,但 OpenMP 出现了,我意识到 ran2(可以说是最好的 RGN)不是线程安全的!实现是here。由于我没有使用过 OpenMP,也没有太多关于多线程的工作,所以我坚持使用 OpenMP 使这个线程安全。

到目前为止,我所知道的是,如果一个函数不修改非本地内存并且不调用任何修改的函数,那么它就已经是线程安全的了。在这种情况下,有 3 个变量是静态的,因此如果被不同的线程使用,将会被修改。

一个可能的解决方案是通过将 ran2 的调用包含在关键部分中以线程安全的方式调用它,但这没有任何意义,因为我没有得到加速。

有人可以指导我如何进行此操作,或者如果有人有任何参考也很棒!

使过程线程安全的通常做法是将以前的静态数据关联到线程本地数据。例如,查看 rand_r() 的手册页,它是 rand() 的线程安全版本。

所以在你的 L'Ecuyer 版本中:

  1. 定义一个保存静态数据的结构(比如状态)

  2. 重新定义过程 ran2() 以具有一个附加参数,该参数是指向此结构状态的指针,并相应地修改代码。设 ran2_r() 为新名称。

  3. 在每个线程中定义一个本地结构状态来保存状态

  4. 可能状态需要播种。您可以使用 get_thread_num() 提供每线程种子以在进入线程时正确初始化状态。

现在您只需要使用指向该状态的指针来调用新的 ran2_r() 即可。它会被程序修改,但修改会存储在线程本地状态变量中。