2017-03-09 20 views
1

有沒有辦法修改R foreach循環如何實現與doParallel後端的負載平衡?當並行執行時間非常不同的任務時,可能發生所有節點,但一個完成其任務,而最後一個節點仍然有幾個任務要完成。這裏是一個玩具的例子:在R foreach循環中的負載均衡

library(foreach) 
library(doParallel) 

registerDoParallel(4) 

waittime = c(10,1,1,1,10,1,1,1,10,1,1,1,10,1,1,1) 

w = iter(waittime) 

foreach(i=w) %dopar% { 
    message(paste("waiting",i, "on",Sys.getpid())) 
    Sys.sleep(i) 
} 

基本上,代碼註冊4核心。對於每個循環i,任務是等待waittime[i]秒。但是,由於foreach循環中的負載平衡默認情況下似乎將任務總數拆分爲具有已註冊核心數量長度的集合,在上例中,第一個核心接收所有任務,其中包括waittime = 10,而其他3人則接收waittime = 1的任務,這樣這3個內核在第一個完成第一個任務之前將完成所有任務。

有沒有辦法讓foreach()分配一個任務?即在上述情況下,我希望前4個任務分佈在4個內核中,然後每個下一個任務分配到下一個可用內核。

謝謝。

回答

3

我還沒有測試它自己,但doParallel後端提供一個preschedule選項類似於在mclapply()mc.preschedule說法。 (見doParallel vignette第7節。)

您可以試試:

mcoptions <- list(preschedule = FALSE) 
foreach(i = w, .options.multicore = mcoptions) 
+0

是的。而已。非常感謝。 – xraynaud

0

道歉發佈作爲答案,但我沒有足夠的代表評論。是否有可能重寫代碼以使用parLapplyLB或parSapplyLB?

parLapplyLB,parSapplyLB是負載平衡的版本中,打算用於施加FUN時X的不同元件需要相當可變的時間量,並且或者功能是確定的或可再現的結果是不需要的。

+0

如果可能的話,我肯定會喜歡住wihth的foreach。在我的應用程序中,foreach循環中的內容比我在示例中放置的兩個命令複雜得多,因此將我的代碼轉換爲單個函數可能會很複雜。不管怎麼說,還是要謝謝你。 – xraynaud

+0

我曾猜測你是一個非常有限的例子,如果你可以使用parLapply函數的形式在forloop中編寫你的代碼很簡單。 – Lespied