1

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))
}

問題は、最初のワーカーが起動してから数秒後に、エンジンが残りのワーカーを起動しようとすることです。すべてのプロセッサでスパイクが見られますが、最初のプロセッサでさえ、すべてすぐに停止します。次に、新しいプロセスが起動され、残りのコードがこの唯一のワーカーを介して実行されます。

さまざまなコードを試してみましたが、エンジンは完全に機能します。しかし、この特定のルーティンでは、そうではありません。

誰かが何が起こっているのか教えてもらえますか?前もって感謝します。

4

1 に答える 1

3

Sys.sleep(0.01)ループ内に を追加すると、 8 つのプロセスすべてがそのプロセスで「ビジー」になっていることがわかります。それらが完了した後、メイン プロセスはしばらくビジーなままです。個々のプロセスからデータを収集し、それを 1 つの結果に結合するオーバーヘッドは、並列化された計算から得られる実際の利益と同程度であると想定しています。単純に「計算」を に変更するとreturn(1)、これは計算とほぼ同じ時間がかかることがわかります。したがって、時間はワークロードに費やされるのではなく、結果の組み立てに費やされます。

これを変更する代わりに.inorder=FALSE使用することも使用することもありません。ただし、オーバーヘッドが大幅に少ないため、これはパッケージの問題であると考えます。doParalleldoMCforeachmclapply

result <- unlist(mclapply(1:nsim, function(i) {
   return(who_wins(probs_a, probs_b))
}, mc.cores=8))
于 2012-07-02T13:21:37.867 に答える