我想使用doMC引擎运行以下代码:
who_wins<-function(probs_a,probs_b,delta_order=0,delta_down=0){
#browser()
team_a<-runif(5,0,1)
team_b<-runif(5,0,1)
sya<-syb<-0
for(i in 1:5){
for(j in 1:2){
if(j==1){
if(sya<syb){
team_a[i]<-(1-delta_down)*team_a[i]
}
team_a[i]<-(1-(i-1)*delta_order)*team_a[i]
sya<-sya+(team_a[i]<probs_a[i])
}
else{
if(syb<sya){
team_b[i]<-(1-delta_down)*team_b[i]
}
team_b[i]<-(1-(i-1)*delta_order)*team_b[i]
syb<-syb+(team_b[i]<probs_b[i])
}
}
}
if(sya>syb){
return(1)
}
else if(sya<syb){
return(2)
}
else {
return(0)
}
}
library(doMC)
registerDoMC(8)
probs_a<-seq(.6,.8,length.out=5)
probs_b<-probs_a[5:1]
nsim<-20000
results<-foreach(icount(nsim), .combine=c) %dopar% {
return(who_wins(probs_a,probs_b))
}
问题是第一个工人启动后几秒钟,引擎试图启动剩余的工作。我看到所有处理器都出现了峰值,但它们都很快死了,甚至是第一个。然后,启动一个新进程,剩下的代码通过这个单独的worker运行。
我尝试了不同的代码片段,引擎完美运行。但是对于这个特定的rutine,它没有。
有谁能告诉我发生了什么事?提前谢谢。
答案 0 :(得分:3)
在你的循环中添加Sys.sleep(0.01)
,我看到所有8个进程都“繁忙”了。完成后,主进程仍然忙碌一段时间。我假设从各个进程收集数据并将其组合到单个结果中的开销与并行计算的实际收益相似。如果您只是将“计算”更改为return(1)
,您将看到这与计算时间一样长,因此不会花费在工作负载上的时间,而是组合结果。
.inorder=FALSE
或使用doParallel
代替doMC
都不会改变这一点。但是,我会在foreach
包中考虑这是一个问题,因为mclapply
的开销要小得多:
result <- unlist(mclapply(1:nsim, function(i) {
return(who_wins(probs_a, probs_b))
}, mc.cores=8))