2017-03-09 12 views
1

R foreachループがdoParallelバックエンドでどのようにロードバランシングを行うかを変更する方法はありますか?非常に異なる実行時間を持つタスクを並列化すると、すべてのノードで発生する可能性がありますが、1つはタスクを終了しますが、最後のタスクはまだいくつかのタスクがあります。ここにおもちゃの例があります:R foreachループのロードバランシング

library(foreach) 
library(doParallel) 

registerDoParallel(4) 

waittime = c(10,1,1,1,10,1,1,1,10,1,1,1,10,1,1,1) 

w = iter(waittime) 

foreach(i=w) %dopar% { 
    message(paste("waiting",i, "on",Sys.getpid())) 
    Sys.sleep(i) 
} 

基本的には、コードレジスタ4コアです。各ループについて、iは、waittime[i]秒待つことです。ただし、foreachループの負荷分散は、既定では、上記の例では、登録されたコアの数の長さを持つセットにタスクの総数を分割するように見えるため、最初のコアはwaittime = 10、他の3人はwaittime = 1のタスクを受け取り、最初のタスクが完了する前にこれらの3つのコアがすべてのタスクを完了するようにします。

foreach()にタスクを1つずつ配布する方法はありますか?すなわち、上記の場合、最初の4つのタスクが4つのコアに分散され、次にそれぞれの次のタスクが次の使用可能なコアに分散されることが望まれます。

ありがとうございました。

答えて

3

私は、それは自分自身をテストしていませんが、doParallelバックエンドはmclapply()mc.preschedule引数に似prescheduleオプションを提供します。 (doParallel vignetteのセクション7を参照してください。)

あなたは試してみてください:

mcoptions <- list(preschedule = FALSE) 
foreach(i = w, .options.multicore = mcoptions) 
+0

はい。それでおしまい。どうもありがとう。 – xraynaud

0

回答として投稿してもお詫び申し上げますが、コメントするには担当者が不十分です。 parLapplyLBまたはparSapplyLBを利用するためにコードを書き直すことは可能でしょうか?

parLapplyLB、parSapplyLBは時間のかなりの可変量をとるXの異なる要素にFUNを適用する際に使用することを目的とロードバランシングのバージョン、あり、そして機能のいずれかは決定論的であるか、再現性のある結果が必要とされていません。

+0

可能ならば、私は間違いなくwihth foreachの滞在を好むだろう。私のアプリケーションでは、foreachループの中にあるものは、私の例で書いた2つのコマンドより複雑です。私のコードを単一の関数に変換するのは複雑かもしれません。とにかくありがとう。 – xraynaud

+0

私はあなたが非常に限られた例をprodcuingしていたと推測していました。もし、あなたのコードを関数の形でforloopの中に書くことができれば、parLapplyは簡単です。 – Lespied