2014-09-25 71 views
2

我正在使用並行處理將變量'marker'傳遞給z_vector。但問題在於它沒有經歷'標記'中的所有值並重復許多值。R並行編程foreach疑惑

library("parallel"); 
library("doParallel"); 
library("foreach"); 

markers=1:100 
c=makeCluster(detectCores()-4); 
registerDoParallel(c,cores=detectCores()-4); ##Using 3 out of 4 cores 

k=0; 

z_vector = foreach (j = 1:100,.combine=c) %dopar% 
{ 
k=k+1; 
marker=markers[k] 
marker 
} 

但是當我輸出的z_vector,我得到這個

z_vector 
    [1] 1 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 
[20] 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 
[39] 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 
[58] 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 
[77] 38 2 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 47 46 
[96] 48 47 49 48 50 

我試圖在Windows上(使用3芯),在那裏我得到的 '1' 重複3次和Linux(使用20芯)我在那裏得到20次重複的'1'。我怎樣才能讓foreach循環完全通過1到100而不重複?爲什麼這些重複發生在第一位? 在此先感謝

+0

是否有任何其他方式來實現代碼,所以我得到正確的輸出?如果您遇到過類似的問題,請將它們帶到討論中。 – LeDon 2014-09-25 04:28:14

+3

這不是一個錯誤,它是一個功能。作業不會共享變量'k',因此具有單獨的計數器,而不是一個。顯而易見的解決方法是使用'j'而不是'k',而不是手動增加它。 – 2014-09-25 04:43:38

+0

謝謝安德烈。但是,許多次R不允許你在foreach調用中使用變量。 – LeDon 2014-09-25 05:47:42

回答

2

對於要並行執行的循環,每次迭代必須獨立於每一個。您不能在並行循環中使用k=k+1等操作,因爲它取決於在先前迭代中計算的「k」值。

在這種情況下,你可以簡單地遍歷「標誌」使用:

z_vector = foreach(marker=markers, .combine=c) %dopar% { 
    marker 
} 

這消除了循環依賴,也可能是更有效,因爲「標記」沒有出口到所有的工人。例如,當遍歷矩陣的列時,這是特別重要的。

+0

謝謝@Steve。 – LeDon 2014-09-25 18:50:00