@parallel 将把要完成的工作分配给立即可用的工作人员。注意在?@parallel 中我们得到The specified range is partitioned ... across all workers. pmap 相比之下,将启动每个工人的工作。一旦一个工人完成了一项工作,它就会给它下一个可用的工作。例如,它类似于 python 中常见的基于队列的多处理。因此,与其说是“重新分配”工作,不如说是只在正确的时间将其分发给正确的工人。
我编写了以下示例,我相信它可以说明这一点。在这个有点傻的例子中,我们有两个工人,一个慢,另一个快两倍。理想情况下,我们希望快速工作人员的工作量是慢工作人员的两倍。 (或者,更现实地说,我们会有快速和慢速的工作,但原则是完全相同的)。 pmap 将完成此操作,但 @parallel 不会。
对于每个测试,我初始化以下内容:
addprocs(2)
@everywhere begin
function parallel_func(idx)
workernum = myid() - 1
sleep(workernum)
println("job $idx")
end
end
现在,对于 @parallel 测试,我运行以下命令:
@parallel for idx = 1:12
parallel_func(idx)
end
并取回打印输出:
julia> From worker 2: job 1
From worker 3: job 7
From worker 2: job 2
From worker 2: job 3
From worker 3: job 8
From worker 2: job 4
From worker 2: job 5
From worker 3: job 9
From worker 2: job 6
From worker 3: job 10
From worker 3: job 11
From worker 3: job 12
几乎是甜的。工人们平均地“分担”了工作。请注意,每个工人完成了 6 份工作,尽管工人 2 的速度是工人 3 的两倍。这可能很感人,但效率很低。
对于pmap 测试,我运行以下命令:
pmap(parallel_func, 1:12)
并获得输出:
From worker 2: job 1
From worker 3: job 2
From worker 2: job 3
From worker 2: job 5
From worker 3: job 4
From worker 2: job 6
From worker 2: job 8
From worker 3: job 7
From worker 2: job 9
From worker 2: job 11
From worker 3: job 10
From worker 2: job 12
现在,请注意,工人 2 已经完成了 8 个工作,而工人 3 已经完成了 4 个工作。这与他们的速度以及我们想要获得最佳效率的速度完全成正比。 pmap 是一个艰巨的任务大师 - 来自每个人的能力。
因此,Julia 文档中的建议是有意义的。如果您有一些简单的小工作,那么@parallel 的这些问题很可能不会引起问题。不过,对于更大或更复杂的工作,pmap 具有优势。