2016-08-30 3 views
0

私はM個の独立したジョブを持っているとします。各ジョブにはN個のステップがあります。ジョブは互いに独立していますが、各ジョブのステップはシリアルでなければなりません。言い換えると、J(i、j)は、J(i、j-1)が終了した後にのみ開始されるべきである(iはジョブインデックスを示し、jはステップを示す)。これは、Mの幅とNの高さを持つ壁を構築することと同形です。Intel MPI分散メモリ:q <Mプロセッサを使用してM * Nブロックから壁を構築する

各ジョブブロックは1回だけ実行する必要があります。 1つのCPUを使用して1つのCPUを使用して(同じ順序でも)1ブロックの作業を行うのにかかる時間は、ブロックごとに異なり、事前には分かっていません。

MPIを使用してこれを行う簡単な方法は、作業ブロックをプロセッサに割り当て、すべてのプロセッサが次の割り当て前にブロックを終了するまで待機することです。このようにして、優先順位を強制することができますが、待ち時間が多くなります。

これを行うより効率的な方法はありますか?つまり、プロセッサが何らかの環境変数や共有メモリを使用して仕事を終え、他のプロセッサが仕事を終えて通信を使用して一括決定を待つことなく、次に行うべき仕事のブロックを決めることができます。

+0

これは、[Wavefront Parallel Processing](http://x265.readthedocs.io/en/default/threading.html#wavefront-parallel-processing)でh.265(ビデオコーデック)と同じように聞こえます。ビデオの各ブロックは、その上のブロックと左のブロックに依存します。そのパターンへの依存関係を制限することで、任意の依存関係よりも多くの並列性が可能になります。そのシステムがあなたのアイデアを得るためにどのように設計されているかを見ることができますが、ジョブ間に依存関係がないことは明らかですが、依然としてお互いに待つ必要があります。 –

+0

Mの仕事はすべて同じような進歩を遂げているのはなぜ重要なのですか? M個のジョブのうちのいくつかが他のジョブが終了するまで(つまり、すべてのN個のステップを単一のジョブスケジューラジョブに入れる)開始しない場合は、問題ありませんか?それとも、それはあなたがいくつかのシリアルジョブが残っているだけなので、すべてのCPUを利用できない状況につながるでしょうか?各ステップのサイズに応じて、キャッシュが重要な場合があるため、同じマシン(同じクラスタノードの同じCPU)上の同じデータに対して複数のステップを実行することが重要になります。 –

+0

もう1つの簡単な方法は、スケジューラ/アービタとして1つのCPU(たとえばp0)を割り当てて、すべてのCPUがフリーであるときに登録する必要があるようにすることです。 p0は適応的にジョブ/ブロックを注文し、それらをCPUに割り当てることができます。これは、いくつかの通信オーバーヘッドの考えを導入するでしょう。同様のことが誰でも自由な人が共有メモリで行うことができます。簡単なピッキングのための「注文」を作成するタスクは共有されます。 – makadev

答えて

1

N個のステップがあるM個のジョブがあります。また、WとMの間のサイズWのワーカー・プロセスもあります。

WがMに近い場合は、1:1に割り当てることをお勧めします。一人の労働者が早期に終了すれば、それは問題ありません。 1つのステップのためのいくつかの平均や典型的な時間を完了するために

  1. 見積り:WはMよりもはるかに小さく、Nもかなり大きい場合

    は、ここでの考え方です。これをTと呼んでください。最初に見積もり率が非常に低い場合に備えて、この見積もりを調整することができます。

  2. M個のジョブをワーカーの数で均等に分割して開始します。 T * N/Kのように、タイムアウトの前にできるだけ多くの作業を割り当てられていることを労働者に伝えます。現在のジョブを終了するためにタイムアウトをわずかにオーバーランニングすることで、前進を確実にすることができます。
  3. 作業員は、完了したステップを互いに連絡します。
  4. 各ジョブの完了度を考慮してジョブを均等に分割します(例:2つの50%完了ジョブは1つの0%完了ジョブと同じです)。

アイデアは、すべての作業者に毎回約1/Kの作業を完了するのに十分な時間を与えることです。 K * T以上の仕事がない場合は、これは非常に効率的です。 1つの共有変数

は維持:n =最も遠いビハインドタスクの進捗

それは良いことだ場合は、合理的なK.はたぶんここアイデアだ10

+0

いくつかの点で私の答えとよく似ていますが、ここではあまりにも先行することはしません。これらの行為がどのように違うかについて面白いことがあると確信していますが、今は空白を描いています。 –

+0

@JohnZwinck私は、MPIで何らかの種類の共有変数を使用する解決策がない場合、統計的最小化は実際には唯一の解決策です。 –

+0

@AmirHajibabaei:MPIは、メッセージの受け渡し用であり、共有メモリ用ではありません。後者を望むなら、例えばRDMAで読むことができます。 –

0

を試す見つけるIDKするのはあなた次第です。すなわち、M個のタスクのいずれかが完了した最低のステップ番号である。すべてのタスクが最初のステップから開始するため、0から開始します。すべてのタスクが少なくとも1ステップずつ完了するまでは0のままです。

プロセッサがジョブのステップを完了したら、現在作業中のステップの進捗状況をnにチェックします。 n < current_job_step - 4の場合は、作業中のタスクが最も遠いタスクより先に進んでいるため、タスクを切り替えます。

私は4を選んで、あまりにも多くの切り替えと2つのタスクであまりにも多くのシリアル作業を行うことのバランスを取っています。必要に応じて調整し、最後に近づけるように適応させることもできます。

すべての決定を下すスケジューラスレッドを持っていない限り、2つのスレッドを持たない切り替えタスクで同じワークユニットを取得することは簡単です。これが単一の共有メモリマシン上にある場合、ロックを使用して優先順位キューを保護することができます。

+0

このアイデアは魅力的ですが、MPIを使ってどのように実装するのかは分かりません。 –

+0

@JohnZwinck:MPIを見てから何年も経ちました。各作業者がそれぞれの作業の進捗状況を管理している場合は、各ステップの完了時にブロードキャストして他の作業者がテーブルを更新できるようにすることができます。しかし、2人の作業者が同じタスクを要求しなくても、タスクを切り替えるという問題はあります。これは共有メモリの問題を解決したものであり、MPIを使用する方法がなければ私はショックを受けます。 –

+0

@AmirHajibabaei:単一のSMPマシン上の複数のスレッドのような、キャッシュ一貫性のある共有メモリシステムでのみ。そうすれば、原子ロックフリーの共有変数を持つことができます。 MPIは共有メモリではなく、メッセージの受け渡し用に設計されているので、すべてのMPIワーカーが同じマシン上にあっても、AFAIKはこれを行うのには本当に役立たないでしょう。 –

関連する問題