2012-03-31 20 views
1

私はpthreadsでスレッドプールを使用することを目指しており、これらの2つのスレッドモデルの中から選択しようとしています。ボス/ワーカーモデルは、動的に変更する作業項目の方が優れています。しかし、私は、ピアプールをスレッドプールでどのくらい正確に動作させるのかについては少し不安です。スレッドプール - ボス/ワーカー対ピアツーワークスモデル

私は、すべて同じデータセットで実行する必要がある多くのタスクがあります。ここで私はこれに取り組んでどのように見えるかについていくつかの簡単な擬似コードだ:

data = [0 ... 999] 
data_index = 0 
data_size = 1000 

tasks = [0 ... 99] 
task_index = 0  

threads = [0 ... 31] 

thread_function() 
{ 
    while (true) 
    { 
     index = data_index++ (using atomics) 
     if index > data_size 
     { 
      sync 

      if thread_index == 0 
      { 
       data_index = 0 
       task_index++ 
       sync 
      } 
      else 
      { 
       sync 
      } 
      continue 
     } 

     tasks[task_index](data[index]) 
    } 
} 

(第一に、ただ1つの同期ポイントこの使用を作る方法があるはずのように思えるが、私はそれが可能だかどうかわからないんだけど? )

上記のコードは、タスクが事前にわかっている場合にはうまくいくようですが、この特定の問題ではスレッドプールは不要です。しかし、データ項目がすべてのタスクにわたって事前定義されていても、タスクが事前に分かっていなければ、ボス/ワーカーモデルがより適しているようです。ボス/ワーカーモデルを使用することは可能ですが、スレッド自体によってタスクが選択されます(上記のように)。ボスは、すべてのタスクが完了するまで本質的に中断します。 (これはまだピアモデルと呼ばれているかもしれません)

最終的な質問は、同期、バリアまたは条件変数に関するものです。なぜですか?

誰かがこの問題に近づいたり、私の前提のいずれかで穴を開けることさえあれば、どんな提案もできます。残念ながら、私はこれに対処するためにtbbのようなより高いレベルのライブラリを使用することに制限されています。

編集:これがはっきりしない場合は、各タスクを完了してから次のタスクに移る必要があります。

+0

データが終了するまで、すべてのスレッドが別のアイテムで同じタスクを実行してから、同期して次のタスクに渡しますか? – Tudor

+0

それは正しいです。アイテム間やタスク間のデータ交換はなく、すべてを独立したものとして扱うことができます。 – Dan

答えて

1

私はここであなたの説明で少し混乱しています、以下が適切であることを願っています。

私はいつもこのパターンを見て、非常に便利であることを発見しました。「ボス」は作業を検出し、それをワーカープールにディスパッチする責任があり、その時から作業員は独立しています。

このシナリオでは、ワーカーは常に他のインスタンスやプロセス要求を意識することなく作業を待っています。終了すると、完了通知がトリガされます。 これは、スレッド間のバランスをとる作業自体とアルゴリズムを適切に分離できるという利点があります。

もう1つの選択肢は、「ボス」が作業アイテムのプールを維持することであり、労働者は自由になるとすぐにそれらを回収することです。しかし、私は実装するのがより複雑で、より多くの同期を必要とすると思います。この2番目のアプローチの利点は前のものに比べてわかりません。

コントロールロジックとワーカーの状態は、両方のシナリオで "ボス"によって維持されます。 タスクで並列処理が行われるので、「ボス」「オブジェクト」はタスクを処理しています。単純な実装では、この「ボス」はタスクが終了するまでブロックし、次の「ボス」を呼び出すことができます。

ここで何かが欠けていない限り、一度同期するだけですべてのワーカーが終了する必要があり、この同期はワーカーが終了した通知を送信する「ボス」で行われます。