2013-02-04 41 views
13

我正在从multicore包(在Ubuntu上)使用mclapply,并且我正在编写一个函数,要求按顺序返回mclapply(x, f)的结果(即f(x[1]), f(x[2]), ...., f(x[n]))。mclapply是否保证按顺序返回结果?

# 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 

上面的代码似乎暗示以相同的次序作为该lapplymclapply返回结果。但是,如果这个假设是错误的,我将不得不花费很长时间来重构我的代码,所以我希望从更熟悉这个包/并行计算的人那里得到保证,这个假设是正确的。

假设mclapply始终按顺序返回结果是否安全?无论提供哪些可选参数?

+1

的文档不表明结果可能会在炒,这是明确的,这是一个并行版本的'lapply',它返回排序的列表作为输入。你可以在顺序和并行模式下运行你的代码的一部分,看看这是否适用于你的特定情况。我会冒险猜测它的确如此。 –

回答

15

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

不过,当然,你应该阅读自己的代码(mclapply为R功能...)

collect手册页给出了一些更多的提示:

注:如果expr采用低级别的多核功能,如sendMaster单个作业可以多次传递结果,用户有责任正确解释它们。

但是,如果你不这样做低层次混乱,

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

(我的重点)

现在对于mclapply。 快速glanc在源代码得到:

  • 如果!mc.preschedule,并且没有比芯(length (X) <= coresparallelcollect使用更多的工作,参见上文。
  • 如果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 - 在cat■不要出现在那里)

相关问题