【问题标题】:Is mclapply guaranteed to return its results in order?mclapply 是否保证按顺序返回其结果?
【发布时间】:2013-01-19 19:28:23
【问题描述】:

我正在使用 multicore 包中的 mclapply(在 Ubuntu 上),我正在编写一个函数,要求按顺序返回 mclapply(x, f) 的结果(即 f(x[1]), f(x[2]), ...., f(x[n])) .

# multicore doesn't work on Windows

require(multicore)
unlist(mclapply(
    1:10,
    function(x){
        Sys.sleep(sample(1:5, size = 1))
        identity(x)}, mc.cores = 2))

[1] 1 2 3 4 5 6 7 8 9 10

上面的代码似乎暗示mclapply 返回结果的顺序与lapply 相同。

但是,如果这个假设是错误的,我将不得不花很长时间重构我的代码,所以我希望从更熟悉这个包/并行计算的人那里得到这个假设是正确的保证。

假设mclapply 总是按顺序返回结果,不管它给出的可选参数是什么,是否安全?

【问题讨论】:

  • 文档没有表明结果可能是乱码的,并且明确指出这是lapply 的并行版本,它返回作为输入排序的列表。您可以在顺序和并行模式下运行部分代码,看看这是否适用于您的特定情况。我敢猜测它确实如此。

标签: r parallel-processing multicore


【解决方案1】:

简短回答:它确实以正确的顺序返回结果。

当然,你应该自己阅读代码(mclapply 是一个 R 函数...)

collect 的手册页提供了更多提示:

注意:如果 expr 使用诸如 sendMaster 之类的低级多核函数,则单个作业可以多次传递结果,用户有责任正确解释它们。

但是,如果你不搞低级,

collect 返回列表中可用的任何结果。 结果将与指定作业具有相同的顺序。如果有多个作业并且一个作业有名称,它将用于命名结果,否则将使用其进程 ID。

(我的重点)

现在为mclapply。 快速浏览一下源代码:

  • 如果使用!mc.preschedule 并且作业数量不超过核心 (length (X) <= cores) parallelcollect,请参见上文。
  • 如果 mc.preschedule 或比核心更多的作业,mclapply 自己会处理订单 - 请参阅代码。

但是,这里是您的实验稍作修改的版本:

> unlist (mclapply(1:10, function(x){
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");    
    identity(x)}, 
  mc.cores = 2, mc.preschedule = FALSE))
1  2  4  3  6  5  7  8  9  10   [1]  1  2  3  4  5  6  7  8  9 10
> unlist (mclapply(1:10, function(x){
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");    
    identity(x)}, 
  mc.cores = 2, mc.preschedule = TRUE))
1  3  2  5  4  6  7  8  10  9   [1]  1  2  3  4  5  6  7  8  9 10

这表明子作业以不同的顺序返回结果(更准确地说:子作业即将以不同的顺序完成),但结果是按原始顺序组装的。

(在控制台上工作,但不在 RStudio 中 - cats 不会出现在那里)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2023-02-16
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多