R foreach%dopar%结果

时间:2018-02-02 23:30:53

标签: r foreach doparallel

我正在尝试使用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中看到的是一个包含10个数据帧的列表,每个数据帧的行数按顺序加倍。

似乎在test_data函数中重新定义foreach不会这样做,就像我只是在标准for循环中运行这些命令一样 - 如下所示:

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

非常感谢我对这里所忽略的内容有所了解。

1 个答案:

答案 0 :(得分:0)

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

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

预防这是concurrency controlsemaphores结构的存在理由。这些允许用户执行您尝试的操作,但需要一些小心才能正确使用。

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

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