【问题标题】:R foreach %dopar% ResultsR foreach %dopar% 结果
【发布时间】:2018-07-13 12:34:51
【问题描述】:

我正在尝试使用foreach%dopar% 运行一个函数,该函数将在每次迭代时将其结果传递回自身。下面的小例子:

require(doParallel)

test_function <- function(data)
{
  result <- rbind(data, data)
  return(result)
}

test_data <- mtcars

cl                          <-          makeCluster(4)
registerDoParallel(cl)
results                     <-          foreach(i = 1:10) %dopar%
{
  aa <- test_function(test_data)
  aa$iteration <- i
  test_data <- aa
  return(aa)
}
stopCluster(cl)

我希望在results 中看到的是一个包含十个数据帧的列表,每个数据帧的行数依次加倍。

似乎在 foreach 函数中重新定义 test_data 并没有这样做,就像我只是在标准 for 循环中运行这些命令一样 - 就像这样:

results <- list()
for(i in 1:10)
{
  aa <- test_function(test_data)
  aa$iteration <- i
  test_data <- aa
  results[[i]] <- aa
}

如果能深入了解我在这里所忽略的内容,将不胜感激。

【问题讨论】:

  • 我不知道你真正的问题是什么,但你要在这里做的事情本质上是连续的。也就是说,第一次运行应该完成它的工作,然后第二次运行,依此类推。它不能并行完成。
  • 是的,我现在看到了。该序列实际上是跨多个处理器并行完成的,这没有意义 b/c 1 需要在 2 开始之前完成。谢谢!
  • 顺便说一句,要禁用foreach 的并行能力,使用%do% 代替%dopar% 就足够了。
  • 使用并行 bc 测试我需要它来解决我的实际问题,现在我意识到这里发生了什么,我需要重新考虑。

标签: r foreach doparallel


【解决方案1】:

如果我正确理解您的问题,您的问题是因为您无法从并行化的 for 循环中更新全局变量 test_data

要了解为什么您被阻止这样做,请考虑并行化 for 循环中实际发生的情况:运行在不同线程上的多个工作人员正在并行执行操作,每个工作人员都有自己独立的局部范围变量。如果他们可以访问任何全局变量(或共享内存)而没有任何类型的保护来控制对它的访问,那么就有可能破坏存储在变量中的任何内容 - 并且这种破坏可能以几种不同的方式发生。

防止这种情况发生是concurrency control 结构(如semaphores)存在的理由。这些允许用户做你想做的事情,但需要小心才能正确使用。

但是,它们在 R 中不可用。因此,R 应该保护全局变量 test_data 不被以非thread safe 方式修改是有道理的。它实际上是在尝试保护您的数据。

解决方案是重写您的代码以消除任何更新全局变量的尝试(如果您仍想进行任何类型的并行处理)或切换到使用传统的顺序 for 循环(正如一些评论者已经建议的那样)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2016-08-02
    • 2011-04-23
    • 2019-07-30
    • 1970-01-01
    • 2016-03-11
    • 2012-11-10
    相关资源
    最近更新 更多