2012-03-30 22 views
5

私はmatlabで長時間実行しているparforループで作業しています。Matlab並列コンピューティングツールボックス、パーフォルループでの作業の動的割り当て

parfor iter=1:1000 
    chunk_of_work(iter); 
end 

実行ごとに約2〜3のタイミング異常値が一般的にあります。すなわち、実行される作業の1000チャンクごとに、残りの約100倍の時間がかかる2-3があります。ループが完了すると、外れ値を評価した作業者は引き続き実行され、残りの作業者は計算負荷がありません。

これは、静的に仕事を分配するparforループと一致しています。これは、並列コンピューティングツールボックスfound hereのドキュメントとは対照的である:。

「ワーク分布は動的である代わりに、固定 反復範囲を割り当てられるが、労働者は彼らの処理を完了のみ 後に新しい反復を割り当てられています現在の反復では、作業負荷分散の場合でも になります。

何が起こっているかについてのアイデアはありますか?

答えて

5

私はあなたが引用した文書は、仕事の静的割り当てとみなされているものをかなりよく説明していると思います。各作業者は「一定の反復範囲を割り当てられています」。 4人の労働者の場合、最初にiter 1:250、2番目にiter 251:500、...または1:4:100、2番目に2:4:1000などが割り当てられます。

あなたはあなたが何を観察しているかはっきり言っていませんでしたが、あなたが説明しているのは動的な負荷分散と一貫しています。まず、4人の労働者が1人ずつiterで働いています。次のものが行われます(これは、最初の4つのうち3つがやや長くなる場合も同じですが、6番目の場合など)。 MATLABがループ反復を処理するために選択した数が20、850、および900の場合、これは100回の時間を要します。これは、21番目から320番目までの反復が4人のうち3人によって解決されることを意味します。 20分で忙しくなります(320分で完了します)。これは、非外れ値計算時間のほぼ均等な分布を前提としています。しかし、850回目の反復を割り当てられた作業者は、別の作業が#1000を解決しても実行を続け、#900も同じ作業を実行します。実際には、約1100の反復があった場合、#900で作業しているものは、他のものがあるときにおおよそ完了する必要があります。あなたが道を見つけない限り、

だから、長い話を短く[仮定すべきではないMATLABは、まだ1000年に1から順にのparforループの反復を割り当てます暗黙のorginal文言としてを編集し]

アウトライアを最初に処理するには(もちろん、どれがアウトライヤであるかを事前に知っておく必要があります。また、MATLABでこれらを使ってparforループ処理を開始する方法を見つけるために)動的ワークロードの分散だけでは、

追加:私が思うに、しかし、その「ループが完了に近づく、労働者が*外れ値を実行し続けて評価 *は」として、以下の

    の少なくとも一つを意味すると思われること、あなたの観察
  1. 外れ値は、何らかの形で反復回数の大きさの順に、MATLABは、あなたは多くの労働者を持っている
  2. を処理するために開始し、最後の反復の間にある
  3. 外れ値の数(2-3)または見積もりの​​見積もりその計算時間のペナルティ(係数100)が低すぎる
3

PARFORの作業分布は多少決定的です。各ワーカーにディスクへのログを記録させることで、何が起きているのかを正確に観察できますが、基本的にPARFORはループを決定的な方法でチャンクに分割しますが、動的に生成します。残念ながら、現在、そのチャンクを制御する方法はありません。

しかし、あなたの1000件のうちどれが外れ値になるのか予測できない場合、その作業を効率的に配分する方法は想像もつきません。

アウトライヤーを予測できる場合は、おおまかに言えば、PARFORはループの反復を逆の順序で実行するので、ループの「最後」に置くことができますそれらはすぐに。

3

あなたが直面する問題は、@ arne.bの答えによく記述されています。私はそれに何も追加しません。

しかし、並列計算ツールボックスには、独立実行のためにjob into tasksを分解する関数が含まれています。あなたの質問から、これが適切であるか、これがあなたのアプリケーションに適していないと結論することはできません。そうであれば、一般的な戦略は、ジョブをある程度の大きさのタスクに分割して、各プロセッサにタスクに取り掛かり、完了したら未完了のタスクのスタックに戻り、別のタスクを開始することです。

1つのループ反復(1つのタスクが多数のタスク、計算の管理には多くのオーバーヘッドがかかるが最適なロードバランシング)に置き換えられるか、1つのタスクがN回のループ反復、オーバーヘッドが少なく、ロードバランシングが不十分です)。ジョブとタスクはparforより実装するのが少し難しいです。

0

PARFORの代わりに、R2013b以降では、PARFEVALを使用して、どのような方法でも作業を分割することができます。適切であれば、十分な結果が得られれば、タイミングアウトライヤーをキャンセルすることもできます。もちろん、既存のループを1000個の個別のPARFEVAL呼び出しに分割する際のオーバーヘッドがあります。多分それは問題かもしれませんが、おそらくそうではありません。ここに私が想像しているものがあります:

for idx = 1:1000 
    futures(idx) = parfeval(@chunk_of_work, 1, idx); 
end 
done = false; numComplete = 0; 
timer = tic(); 
while ~done 
    [idx, result] = fetchNext(futures, 10); % wait up to 10 seconds 
    if ~isempty(idx) 
     numComplete = numComplete + 1; 
     % stash result 
    end 
    done = (numComplete == 1000) || (toc(timer) > 100); 
end 
% cancel outstanding work, has no effect on completed futures 
cancel(futures); 
関連する問題