2014-09-25 72 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