シリアルで正常に実行され、ローカル マシン (3 コア) で並列で正常に実行されるプロセスが、クラスター上の多くのコアで実行されると速度が低下する可能性がある理由をトラブルシューティングしようとしています。コードはローカルで問題なく動作するため、動作しない最小限の例を実際に作成することはできません。
各ワーカーの出力をファイルに保存するようにスクリプトを変更しました。後でファイルのゴブを集約します。何かが欠けていない限り、コミュニケーションと集約ではないと思います。
これが私の出力です。かなり複雑なプロセスのラッパー関数を示しています。これは、実行する前に一度単独で実行しますplyr
。
> analyze_ = function(r){#wrapper function with error handling
+ sti = proc.time()
+ out<-tryCatch(analyze(r)
+ , error=function(e) e, finally=1+1)
+ if(inherits(out, "error")) {
+ out='error!'
+ print(paste("an error happened at",r[1],r[2]))
+ }
+ print(proc.time()-sti
+ }
>
> st = proc.time()
> x = analyze_(xygrid[1,])
[1] "Successfully did -0.25 100.25"
user system elapsed
8.282 0.008 8.286
次に、コードを並行して実行すると、すべてが遅くなります。
> nodes <- detectCores()
> nodes
[1] 24
> registerDoMC(nodes)
> output<-a_ply(xygrid,1,analyze_, .parallel=T)
[1] "Successfully did 0.25 102.25"
user system elapsed
9.292 0.042 221.954
[1] "Successfully did 0.25 10.25"
user system elapsed
9.298 0.039 221.994
[1] "Successfully did -0.25 102.75"
user system elapsed
9.313 0.054 222.808
[1] "Successfully did -0.25 102.25"
user system elapsed
9.328 0.043 222.832
[1] "Successfully did -0.25 104.25"
user system elapsed
9.250 0.032 223.761
[1] "Successfully did -0.25 103.75"
user system elapsed
9.258 0.038 223.786
この種の動作を引き起こす可能性のあるものにはどのようなものがありますか? 既に述べたように、関数は出力を破棄し、シリアル実行時にベンチマーク速度を維持し、ローカル マシンの 3 つのコアで並列に正常に動作します。
「経過」時間が「ユーザー」時間のほぼ正確に 24 倍になるのはなぜですか。(とにかく「ユーザー」時間は何ですか?)
編集コメントの質問に答えて、並列と直列のパフォーマンスを直接比較します。並列は実際には遅いです。
> system.time(analyze_(xygrid[1,]))
user system elapsed
8.223 0.005 8.250
>
> nodes <- detectCores()
> nodes
[1] 24
> registerDoMC(nodes)
>
> system.time(a_ply(xygrid[1:24,],1,analyze_, .parallel=F))
user system elapsed
197.666 0.072 197.762
>
> system.time(a_ply(xygrid[1:24,],1,analyze_, .parallel=T))
system elapsed
119.871 0.401 206.257
Edit2 コードはログイン ノードで正常に動作します。各ジョブは連続して 6 秒かかり、24 の並列ジョブは 12 秒かかります。では、計算ノードは一般的にログイン ノードとどのように異なるのでしょうか?
Edit3
Solvedibrun
ジョブを複数のスレッドに送信するシェル スクリプト
を使用していることがわかりました。ただし、R は、R ジョブを呼び出すシェル スクリプトからではなく、R 内から並列バックエンドが呼び出される「スレッド並列処理」と呼ばれるものを使用します。バッチ処理コマンドから複数のスレッドを呼び出すと、クラスターは各コアで並列ジョブを実行します。したがって、コア数のおおよその倍数である速度。したがって、話の教訓: 共有リソース システム上の 1 つのスレッドについてのみバッチ処理システムに要求し、使用される実際のコアの数を R に処理させます。そして、この問題はおそらく、バッチ処理システムを備えた共有スーパーコンピューターにのみ関連します。