1

嵌套parallel::mclapply调用是个好主意吗?

require(parallel)
ans <- mclapply(1:3, function(x) mclapply(1:3, function(y) y * x))
unlist(ans)

输出:

[1] 1 2 3 2 4 6 3 6 9

所以它是“工作”。但它是否推荐用于真正的计算密集型任务,这些任务的数量超过了内核的数量?执行此操作时发生了什么?涉及的多个分叉是否更可能造成浪费?mc.cores和的考虑因素是mc.preschedule什么?

编辑 只是为了澄清动机,通常通过拆分一个维度来并行化似乎很自然(例如,使用不同的核心来处理来自n 个不同年份的数据),然后在这种拆分中出现另一种自然的拆分方式(例如,使用不同的核心来计算m个不同功能中的每一个)。当 m 乘以 n 小于可用内核的总数时,上述嵌套看起来是合理的,至少从表面上看是这样。

4

1 回答 1

2

在下面的实验中,测试函数的并行testfn()执行比嵌套并行执行更快:

library(parallel)
library(microbenchmark)
testfn <- function(x) rnorm(10000000)

microbenchmark('parallel'= o <- mclapply(1:8, testfn, mc.cores=4),
               'nested'  = o <- mclapply(1:2, function(x) mclapply(1:4, testfn, mc.cores=2), 
                                         mc.cores=2),
               times=10)
Unit: seconds
     expr      min       lq     mean   median       uq      max neval
 parallel 3.727131 3.756445 3.802470 3.815977 3.834144 3.890128    10
   nested 4.355846 4.372996 4.508291 4.453881 4.578837 4.863664    10

解释
R 会话和四个 R 工作人员之间的通信似乎比 R 会话和两个工作人员之间的通信更有效,两个工作人员又分叉并分别与其他两个工作人员进行通信。

替代方案foreach
包可以处理嵌套循环,这接近于嵌套调用;请参阅小插图https://cran.r-project.org/web/packages/foreach/vignettes/nested.pdfmclapply()

(参数的最佳设置mc.preschedule取决于具体问题;请参阅帮助页面?mclapply。)

于 2018-11-04T03:40:08.687 回答