1

処理する必要のある要素を含むキューがあります。これらの要素を並行して処理したいと思います。同期する必要がある各要素のいくつかのセクションになります。いつでも、スレッドを実行している最大num_threadsが存在する可能性があります。

私が達成したいことのアイデアをあなたに与えるためのテンプレートを提供します。

queue q

process_element(e)
{
    lock()
    some synchronized area
    // a matrix access performed here so a spin lock would do
    unlock()
    ...
    unsynchronized area
    ...
    if( condition )
    {
        new_element = generate_new_element()
        q.push(new_element) // synchonized access to queue
    }
}

process_queue()
{
    while( elements in q ) // algorithm is finished condition
    {
         e = get_elem_from_queue(q) // synchronized access to queue
         process_element(e)
    }
}

使うことができます

  • pthreads
  • openmp
  • インテルスレッドビルディングブロック

私が抱えている主な問題

  • いつでも、最大num_threadsのスレッドを実行していることを確認してください
  • キューで使用する軽量の同期方法

私の計画は、キューコンテナのInteltbbconcurrent_queueです。しかし、その後、pthread関数(ミューテックス、条件)を使用できますか?これが機能すると仮定しましょう(そうする必要があります)。次に、pthreadを使用して、ある時点で最大num_threadsを設定するにはどうすればよいですか?一度スレッドを作成し、1つの要素がプロセスになった後、キューにアクセスして次の要素を取得することを考えていました。ただし、キューに要素がない場合にアルゴリズムが終了するという保証がないため、より複雑な場合。

私の質問

実装を開始する前に、Intel tbbまたはpthreadを使用して必要な動作を取得する簡単な方法があるかどうかを知りたいですか?キューからの要素をより正確に並列処理する

注:タスクを使用しようとしましたが、成功しませんでした。

4

3 に答える 3

1

まず第一に、pthreads は移植性を提供します。あなたの質問から次のことが当てはまるようです - 答えが変わるので、これらが真実でない場合はお知らせください: 1) コードを実行しているマルチコア プロセッサがあります。 (1) の理由でnum_threadsスレッドを超えないようにする

上記が当てはまると仮定すると、次のアプローチがうまくいく可能性があります。

  1. pthread_create を使用してnum_threads 個のpthreads を作成します
  2. オプションで、各スレッドを異なるコアにバインドします
  3. q.push(new_element) は、new_element をキューにアトミックに追加します。ここでは pthreads_mutex_lock と pthreads_mutex_unlock が役に立ちます。例: http://pages.cs.wisc.edu/~travitch/pthreads_primer.html
  4. 要素のデキューに pthreads_mutexes を使用する
  5. 終了には注意が必要です。これを行う 1 つの方法は、キューに TERMINATE 要素を追加することです。これにより、デキュー時に、デキュー者が (次のデキュー者のために) 別の TERMINATE 要素をキューに入れ、終了します。キューに 1 つの余分な TERMINATE 要素ができてしまいますが、これは、すべてのスレッドが完了した後に、名前付きスレッドでデキューすることで削除できます。

キューから要素を追加/削除する頻度に応じて、要素をキューに入れたりキューから取り出したりするために、 pthread_mutex_... よりも軽量なものを使用することができます。これは、よりマシン固有の構造を使用したい場合がある場所です。

于 2012-12-12T18:05:43.250 に答える
0

私のお勧めは、 を見ることですtbb::parallel_do。コンテナー自体が並行していなくても、コンテナーの要素を並行して処理するように設計されています。つまり、ユーザーの同期なしparallel_doで で正しく動作します (もちろん、内部でマトリックスへのアクセスを保護する必要があります。さらに、新しい要素を作業キュー (唯一の注意点は、すべての「古い」アイテムが終わるまで処理を延期するキューに入れるのとは異なり、新しく追加された作業がすぐに処理されることです). また、終了について心配する必要はありません:自動的に完了しますすべての初期キュー アイテムとその場で作成された新しいアイテムが処理されるとすぐに。std::queueprocess_element()parallel_doprocess_element()parallel_do

ただし、計算自体に加えて、作業キューが別のソース (I/O 処理スレッドなど) から同時に供給される場合parallel_doは、適切ではありません。parallel_pipelineこの場合、 TBB フロー グラフを見るのが理にかなっているかもしれません。

最後に、アプリケーションは TBB を使用してアクティブなスレッドの数を制御できますが、これは推奨される方法ではありません。

于 2012-12-20T20:07:39.680 に答える
0

TBB は他のスレッド化パッケージと互換性があります。

TBB はスケーラビリティも重視します。したがって、プログラムをデュアル コアからクアッド コアに移植する場合、プログラムを調整する必要はありません。データ並列プログラミングでは、プロセッサを追加すると、プログラムのパフォーマンスが向上 (スケーリング) します。

Cilk Plus も、良い結果をもたらすもう 1 つのランタイムです。

www.cilkplus.org

pThreads は低レベルのスレッド ライブラリであるため、アプリケーションに必要な制御の量を決定する必要があります。これは柔軟性を提供しますが、プログラマの労力、デバッグ時間、およびメンテナンス コストの点でコストが高くなります。

于 2012-12-12T18:33:31.800 に答える