foreach、doParallel 和随机生成

Posted

技术标签:

【中文标题】foreach、doParallel 和随机生成【英文标题】:foreach, doParallel and random generation 【发布时间】:2017-09-04 02:18:11 【问题描述】:

考虑使用并行foreach 生成随机值的非常基本(且效率低下)的代码:

cl <- makeCluster(2)
registerDoParallel(cl)
foreach(i = 1:100) %dopar% rnorm(1)

它是正确的还是需要任何额外的步骤才能使随机生成正常工作?我想这已经足够了,快速检查似乎“证明”种子可以正常工作,但我想确保它在其他平台上也是如此,因为我希望代码是可移植的。

【问题讨论】:

这合并为两个重要的子任务: A:确保对某些 PRNG 的并行调用正常工作(线程安全、阻塞等),其中更安全的方法是为每个线程/进程使用一个 PRNG (不确定这里进行了哪种并行化)和 B:(在不同 PRNG 的情况下)确保这些种子能够产生良好的随机数。许多 PRNG 在这方面存在很多缺陷(例如,使用种子初始化的 Mersenne-Twister:0、1、2 -> 坏)。进一步搜索的关键字是:分布式播种(有很多方法:跳跃式;PRNG 跳跃,.)。 谢谢。但是通用的最新包like plyr 似乎并不关心它。这是否意味着它们不应该用于此类目的? 【参考方案1】:

你的担心是对的;随机数生成不会神奇地并行工作,需要采取进一步的步骤。在使用 foreach 框架时,您可以使用 doRNG 扩展来确保在并行完成时也能获得正确的随机数。

例子:

library("doParallel")
cl <- makeCluster(2)
registerDoParallel(cl)

## Declare that parallel RNG should be used for in a parallel foreach() call.
## %dorng% will still result in parallel processing; it uses %dopar% internally.
library("doRNG")

y <- foreach(i = 1:100) %dorng% rnorm(1)

编辑 2020-08-04:以前这个答案提出了替代方案:

library("doRNG")
registerDoRNG()
y <- foreach(i = 1:100) %dopar% rnorm(1)

但是,这样做的缺点是开发人员在函数内部以干净的方式使用registerDoPNG() 更加复杂。因此,我建议使用%dorng% 来指定应该使用并行RNG。

【讨论】:

谢谢,+1。我听说过doRNG,但从未使用过。您能否评论一下使用registerDoRNG() 与使用%dorng% 有何不同...?它们是一样的吗? 我对细节生疏了,但是 doRNG 小插图应该能回答你的问题。 顺便问一下,doFuture 会处理 RNG 种子吗? 不,doFuture 只是将 future 封装到 foreach 框架中的一个薄层——它将 RNG 需求传递给 foreach / doRNG。

以上是关于foreach、doParallel 和随机生成的主要内容,如果未能解决你的问题,请参考以下文章

一段 R 代码会影响 foreach 输出中的随机数吗?

R doParallel foreach 中的并行处理

在 R 中将 fread 与 foreach 和 doParallel 一起使用

Foreach和doparallel而不是R中的for循环

有没有办法在 xts 中将 period.apply 与 doParallel 和 foreach 一起使用?

使用 foreach 函数和 doParallel 库在 R 中嵌套 for 循环