何時使用 parallel 與 pmap
Julia 文件建議這樣做
pmap()
是針對每個函式呼叫執行大量工作的情況而設計的。相比之下,@ parallel for 可以處理每次迭代很小的情況,也許只是將兩個數相加。
有幾個原因。首先,pmap
會帶來更大的啟動成本,從而為員工創造就業機會。因此,如果作業非常小,這些啟動成本可能變得低效。然而,相反,pmap
在工人中分配工作的聰明工作。特別是,它構建了一個作業佇列,並在該工作人員可用時向每個工作人員傳送新作業。相比之下,@parallel
將所有工作分配給工人。因此,如果一些工人的工作時間比其他工人長,那麼你最終可能會遇到這樣的情況,即大多數工人已經完成並且閒置,而少數工人在過長的時間內仍然活躍,完成工作。然而,這種情況不太可能發生在非常小而簡單的工作中。
以下說明了這一點:假設我們有兩個工人,其中一個工作緩慢,另一個工作速度快兩倍。理想情況下,我們希望快速工作者的工作量是慢工作者的兩倍。 (或者,我們可以有快速和慢速的工作,但校長完全相同)。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
是一個艱鉅的任務大師 - 從每個人的能力。