【问题标题】:Should mclapply calls be nested?mclapply 调用应该嵌套吗?
【发布时间】:2018-08-06 12:16:43
【问题描述】:

嵌套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.coresmc.preschedule有哪些注意事项?

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

【问题讨论】:

    标签: r parallel-processing mclapply


    【解决方案1】:

    在下面的实验中,测试函数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 session 和四个 R worker 之间的通信似乎比 R session 和两个 worker 之间的通信更有效,两个 worker 又分叉并分别与另外两个 worker 通信。

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

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

    【讨论】:

    • 小插图链接已损坏
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 2013-08-11
    • 2014-03-14
    • 2022-12-16
    • 1970-01-01
    • 2016-12-02
    相关资源
    最近更新 更多