我遇到了一个奇怪的问题clusterApply
,我已经能够尽可能地隔离它,如下所示。首先,我从全局环境运行以下代码:
require(parallel)
cl<-makeCluster(rep("localhost",20),"SOCK")
xl<-list()
for(i in 1:20)
xl[[i]]<-crossprod(matrix(rnorm(1e6),1000,1000))
x<-xl
clusterExport(cl,"x",environment())
f0<-function(z) eigen(x[[z]])
system.time(clusterApply(cl,1:20,f0))
## user system elapsed
## 0.332 0.264 3.334
现在,为了确保没有发生任何奇怪的情况,请重新启动 R,然后运行这段类似的代码,该代码调用clusterApply
从函数内部:
require(parallel)
cl<-makeCluster(rep("localhost",20),"SOCK")
xl<-list()
for(i in 1:20)
xl[[i]]<-crossprod(matrix(rnorm(1e6),1000,1000))
f<-function(clust,x){
force(x)
clusterExport(clust,"x",environment())
f0<-function(z) eigen(x[[z]])
print(system.time(clusterApply(clust,1:20,f0)))
}
f(cl,xl)
## user system elapsed
## 5.212 1.888 13.627
我做了一些搜索并发现这个相关问题的答案 https://stackoverflow.com/a/18037825/2588184,它指出未在全局环境中定义的函数中使用的局部变量将导出到集群。所以我想,也许问题在于x
被导出两次,这就是花费很长时间的时间,而不是实际的函数调用。为了测试这一点,我将函数定义更改为:
f0<-function(z) eigen(get("x")[[z]])
我的表现仍然很慢。有谁知道这里会发生什么?
顺便说一句,如果我只是打电话
clusterApply(clust,x,eigen)
在函数内部,那么它就可以正常工作,就像在全局环境中一样快。当然,如果这是我想要解决的问题,我会简单地这样做,但事实并非如此,这只是一个玩具问题,用于隔离我与其他更复杂的代码遇到的问题。