【问题标题】:R parallel programming foreach doubtsR并行编程foreach的疑惑
【发布时间】:2014-09-25 03:15:31
【问题描述】:

我正在使用并行处理将变量“标记”传递给 z_vector。但问题是它没有遍历“标记”中的所有值并重复许多值。

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 个内核)上尝试了 3 次重复的“1”和 Linux(使用 20 个内核),我得到了 20 次重复的“1”。如何使 foreach 循环准确地通过 1 到 100 而不重复?为什么这些重复首先会发生? 提前致谢

【问题讨论】:

  • 有没有其他方法可以实现代码,以便我得到正确的输出?如果您也遇到过类似的问题,也请大家一起讨论。
  • 这不是一个错误,而是一个特性。这些作业不共享变量k,因此有单独的计数器,而不是一个。明显的解决方法是使用j 而不是k,而不是手动增加它。
  • 谢谢安德烈。但是,很多时候 R 不允许您在 foreach 调用中使用该变量。
  • 这是一个警告,您必须找到解决方法。这可能是我不使用foreach 的原因。我更喜欢旧的经典循环,我使用循环变量 j 提取相关数据。
  • foreach 循环的迭代器被指定为第一个参数。这与for 循环基本相同。

标签: r foreach parallel-processing


【解决方案1】:

对于要并行执行的循环,每次迭代都必须相互独立。您不能在并行循环中使用诸如 k=k+1 之类的操作,因为它取决于在前一次迭代中计算的“k”值。

在这种情况下,您可以使用以下方法简单地迭代“标记”:

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

这消除了循环依赖,并且还可能更有效,因为“标记”不必导出到所有工作人员。例如,在遍历矩阵的列时,这一点尤其重要。

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2017-02-16
    • 2013-09-06
    • 2016-07-11
    • 2013-08-12
    • 2016-05-30
    相关资源
    最近更新 更多