0

外側のループがシーケンシャルである必要があり、内側のループが非常に単純なオブジェクトを介して前の反復に依存するネストされたループを作成する場合、セッション間で複数回通信することによるオーバーヘッドを削減する方法はありますか?

doMCと を使用した例を次に示しforeachます。

library(doMC)
library(tictoc)

registerDoMC(3)

tic()
a <- runif(100)
for(i in seq_len(333)){
  a <- foreach(j = 1:100, .combine = c) %dopar% {
    sqrt(a[j])*sqrt(max(a))
  } 
}
toc()
#> 7.669 sec elapsed

tic()
a <- runif(100)
for(i in seq_len(333)){
  a <- foreach(j = 1:100, .combine = c) %do% {
    sqrt(a[j])*sqrt(max(a))
  } 
}
toc()
#> 5.224 sec elapsed

reprex パッケージ(v0.3.0)により 2019-07-22 に作成

内部ループの計算は非常に単純であるため、複数のセッションを作成してデータを転送することから生じるオーバーヘッドにより、並列バージョンは順次バージョンよりも遅くなります。

コードをプロファイリングした後、予想どおり、時間差は主に から来ていmcforkますが、計算は非常に単純で、ベクトルのみが原因で呼び出し間で異なるため、呼び出し間でセッションを持続させて送信のみaにする方法があるかどうか疑問に思っていました各呼び出し間foreachaベクトル (これは、セッション全体をフォークするよりもはるかに高速になるはずです)。

のセッション分岐構造でそれを達成する方法はありdoMCますか? この種のソリューション (タスク間の小さな変更でセッションを維持する) が可能な別の並列バックエンドはありますか?

4

1 に答える 1