在多核上使用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
答案 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
中提取结果并将其存储为对象(例如globalVariable
,globalVariable2
等)。
globalVariable1 <- do.call(cbind, lapply(theRes, "[[", 1))
globalVariable2 <- do.call(cbind, lapply(theRes, "[[", 2))
考虑到这一点,如果您在每次迭代中执行的计算取决于先前迭代的计算结果,那么这种类型的并行计算不是采用的方法。