mclapply是否保证按顺序返回结果?

Rya*_*ell 13 parallel-processing multicore r

我的工作mclapplymulticore包(在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
Run Code Online (Sandbox Code Playgroud)

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

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

是否可以安全地假设mclapply始终按顺序返回结果,而不管它是否给出了可选参数?

cbe*_*ica 15

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

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

手册页提供collect了一些提示:

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

但是,如果你不贬低低级别,

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

(我的重点)

现在为mclapply.对源代码的快速glanc产生:

  • 如果!mc.preschedule并且没有更多的作业而不是core(length (X) <= cores)parallel并且collect被使用,请参见上文.
  • 如果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
Run Code Online (Sandbox Code Playgroud)

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

(适用于控制台,但不适用于RStudio - cats不会显示在那里)