外側のループがシーケンシャルである必要があり、内側のループが非常に単純なオブジェクトを介して前の反復に依存するネストされたループを作成する場合、セッション間で複数回通信することによるオーバーヘッドを削減する方法はありますか?
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
にする方法があるかどうか疑問に思っていました各呼び出し間foreach
のa
ベクトル (これは、セッション全体をフォークするよりもはるかに高速になるはずです)。
のセッション分岐構造でそれを達成する方法はありdoMC
ますか? この種のソリューション (タスク間の小さな変更でセッションを維持する) が可能な別の並列バックエンドはありますか?