15

私はパッケージmclapplyからmulticore(Ubuntuで)作業しており、の結果が順番に返されることを必要とする関数を書いていますmclapply(x, f)(つまり、f(x[1]), f(x[2]), ...., f(x[n]))。

# multicore doesn't work on Windows

require(multicore)
unlist(mclapply(
    1:10,
    function(x){
        Sys.sleep(sample(1:5, size = 1))
        identity(x)}, mc.cores = 2))

[1] 1 2 3 4 5 6 7 8 9 10

上記のコードはmclapply、 が と同じ順序で結果を返すことを暗示しているようlapplyです。

ただし、この仮定が間違っている場合は、コードのリファクタリングに長い時間を費やす必要があるため、このパッケージ/並列計算に精通している誰かから、この仮定が正しいことを保証してもらいたいと考えています。

mclapply指定されたオプションの引数に関係なく、常に結果を順番に返すと仮定しても安全ですか?

4

1 に答える 1

19

簡単な答え: 正しい順序で結果を返します。

しかしもちろん、コードは自分で読む必要があります (mclapplyは R 関数です...)

のマニュアルページにcollectは、さらにヒントがいくつかあります。

注: expr が sendMaster などの低レベルのマルチコア関数を使用する場合、1 つのジョブで結果が複数回配信される可能性があり、それらを正しく解釈するのはユーザーの責任です。

ただし、低レベルをいじらないと、

collect は、リストで使用可能なすべての結果を返します。結果は、指定されたジョブと同じ順序になります。複数のジョブがあり、ジョブに名前がある場合は、結果の名前に使用されます。それ以外の場合は、そのプロセス ID が使用されます。

(私の強調)

今すぐmclapply。ソースコードをざっと見てみると、次のようになります。

  • コア ( )!mc.prescheduleより多くのジョブがなく、使用されている場合は、上記を参照してください。length (X) <= coresparallelcollect
  • mc.prescheduleコアよりも多くのジョブがある場合、それmclapply自体が順序を処理します - コードを参照してください。

ただし、実験のわずかに変更されたバージョンは次のとおりです。

> unlist (mclapply(1:10, function(x){
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");    
    identity(x)}, 
  mc.cores = 2, mc.preschedule = FALSE))
1  2  4  3  6  5  7  8  9  10   [1]  1  2  3  4  5  6  7  8  9 10
> unlist (mclapply(1:10, function(x){
    Sys.sleep(sample(1:5, size = 1)); 
    cat (x, " ");    
    identity(x)}, 
  mc.cores = 2, mc.preschedule = TRUE))
1  3  2  5  4  6  7  8  10  9   [1]  1  2  3  4  5  6  7  8  9 10

これは、結果が子ジョブによって異なる順序で返されることを示しています (より正確には、子ジョブは異なる順序で終了しようとしています) が、結果は元の順序で組み立てられます。

(コンソールでは機能しますが、RStudio では機能しcatません - s は表示されません)

于 2013-02-06T22:59:40.010 に答える