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 跳跃,.)。 谢谢。但是通用的最新包likeplyr
似乎并不关心它。这是否意味着它们不应该用于此类目的?
【参考方案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 中将 fread 与 foreach 和 doParallel 一起使用