使用doSNOW写入全局变量并在R中进行并行化?

时间:2012-02-22 22:21:55

标签: r foreach

在多核上使用doSNOW包访问/写入全局变量时是否存在问题?

在下面的程序中,每个MyCalculations(ii)都写入矩阵“globalVariable”的第ii列......

您认为结果是否正确?会有隐藏的捕获量吗?

非常感谢!

P.S。我必须写出全局变量,因为这是一个简单的例子,事实上我有很多输出需要从并行循环中传输...因此,可能唯一的方法是写出全局变量。 ..

library(doSNOW)
MaxSearchSpace=44*5
globalVariable=matrix(0, 10000, MaxSearchSpace)
cl<-makeCluster(7)
registerDoSNOW(cl)
foreach (ii = 2:nMaxSearchSpace, .combine=cbind, .verbose=F) %dopar%
  {
   MyCalculations(ii)
  }

stopCluster(cl)

P.S。我问 - 在DoSnow框架内,是否存在访问/编写全局变量的危险...... thx

1 个答案:

答案 0 :(得分:7)

由于这个问题已经有几个月了,我希望你现在已经找到了答案。但是,如果您仍然对反馈感兴趣,请考虑以下事项:

foreach与并行后端一起使用时,您将无法以您尝试的方式分配给R的全局环境中的变量(您可能已经注意到了这一点)。使用顺序后端,分配将起作用,但不能使用与doSNOW类似的 parallel

相反,将每个迭代的计算结果保存在列表中并将其返回给对象,以便在完成所有计算后提取相应的结果。

我的建议与你的例子类似:

library(doSNOW)
MaxSearchSpace <- 44*5
cl <- makeCluster(parallel::detectCores())

# do not create the globalVariable object

registerDoSNOW(cl)

# Save the results of the `foreach` iterations as 
# lists of lists in an object (`theRes`)

theRes <- foreach (ii = 2:MaxSearchSpace, .verbose=F) %dopar%
  {
# do some calculations
   theNorms <- rnorm(10000)
   thePois <- rpois(10000, 2)
# store the results in a list
   list(theNorms, thePois)
  }

完成所有迭代后,从theRes中提取结果并将其存储为对象(例如globalVariableglobalVariable2等)。

globalVariable1 <- do.call(cbind, lapply(theRes, "[[", 1))
globalVariable2 <- do.call(cbind, lapply(theRes, "[[", 2))

考虑到这一点,如果您在每次迭代中执行的计算取决于先前迭代的计算结果,那么这种类型的并行计算不是采用的方法。