【问题标题】:How to modify shared objects using foreach loop in R?如何使用 R 中的 foreach 循环修改共享对象?
【发布时间】:2020-02-23 05:43:22
【问题描述】:

我正在尝试通过将 for-loop 并行转换为 for-each 循环来加速它。但是,当它需要修改一些共享对象时,会带来一些问题。一个玩具示例如下。

library(doParallel)
registerDoParallel(cores = 4)
a <- c()
b <- c()
foreach(i = 1:100, .combine = cbind) %dopar% {
  a <- c(a, i)
  b <- c(b, i^2)
  NULL  # to take up a place for the return statement
}
a
b

理想情况下,我希望矢量ac(1, 2, 3, ..., 100)bc(1, 4, 9, ..., 10000),其中元素的顺序无关紧要。但是,上述代码 sn-p 的结果是向量 a 和向量 b 都是空的。

任何人都知道发生了什么以及如何解决它?

谢谢!

-- 编辑--
为了给你更多的背景信息,我正在尝试在 R 中并行化 BFS 算法。代码的骨架如下所示:

q <- queue()
s <- set()
l <- list(...)
while(length(q) > 0){
  element <- pop(q)
  for(edge connect to element){
    if(!s contains edge && some other conditions){
      s <- set_union(s, <something new>)
      pushback(q, <something new>)
      l[[1]] <- <something new>
    }
  }
}

我正在尝试将内部 for 循环转换为 foreach 循环,该循环可以将这些边缘的计算分散到不同的核心。但是,数据结构集、队列和列表是共享的。如果没有简单的方法来获取它们的锁,它们有没有对应的并发数据结构,比如Java中HashMap的ConcurrentHashMap?

【问题讨论】:

  • 在我的真实代码中,我将在 foreach 循环中修改一个列表、一个队列和一个集合。如果上面的代码没有快速修复,一些关于它们对应的并发数据结构的建议也有帮助。谢谢!
  • 抱歉,这根本不可能。如果你想使用并行计算,你必须编写一个没有副作用的循环。研究 foreach 包小插图。
  • @Roland:由于我正在尝试学习并行计算:如果您愿意为我指出:代码示例中的“副作用”“发生”在哪里?跨度>
  • 副作用是将子集分配到循环外的对象中。

标签: r parallel-foreach


【解决方案1】:

我不确定这是否是 OP 所追求的,但它按预期返回了一个带有两个向量的 data.frame:

library(doParallel)
registerDoParallel(cores = 4)
result <- foreach(i = 1:10, .combine = rbind) %dopar% {
  a <- i
  b <- i^2
  data.frame(a, b)
}
result
    a   b
1   1   1
2   2   4
3   3   9
4   4  16
5   5  25
6   6  36
7   7  49
8   8  64
9   9  81
10 10 100

请注意,我已将迭代次数减少到 10 次以进行演示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 2019-03-09
    • 1970-01-01
    相关资源
    最近更新 更多