2011-01-28 10 views
2

私は、スレッドプールがOpenMP文を含むコードブロックを実行すると考えていました。 (類似:How to deal with OpenMP thread pool contentionと思います)。 OpenMP並列領域が毎回別のスレッドで実行されると、問題が発生したり、パフォーマンスが低下するかどうかという疑問があります。スレッドプールで実行されたOpenMPコード

編集:

ターゲットは、Linux(GCC)およびWindows(MSVC)となります。

最初のプロトタイプが完成した時点でベンチマークを行います(ここで得られる回答の影響を受けます)。今、あなたはTaskのインスタンスは、スレッドプール(スレッド0、...、スレッド-N)にそれを与える作成想像

class Task 
{ 
public: 
    void doTask() 
    { 
     #pragma omp parallel 
     { 
      // do work in parallel 
     } 
    } 
}; 

は、ここで簡単な例です。 1つのスレッドはdoTask()を実行します。後で同じタスクオブジェクトをスレッドプールに戻します。もう一度、...。 したがってdoTask()(およびパラレルセクション)は異なるスレッドによって実行されます。私はこれがOpenMPによって効率的に処理されるかどうか疑問に思います(例えば、セクションのスレッドは毎回再作成されません)。

+0

どのコンパイラでですか? –

+2

私の経験でコードを最適化するには、何かがパフォーマンスの向上につながるかどうかを知るための単一の方法があります。何かが遅いかどうかを考え、仮説を作成することは、実装があまりにも複雑な場合にのみ有用です。現実的なテストデモを作成し、それをベンチマークします。 –

答えて

4

Vitorさんのコメントは正しくありません。回答が多くの要因(データレイアウト、データへのアクセス方法、キャッシュサイズ、実行中のプロセッサのタイプ、リストなど)に依存するため、これが問題を引き起こすかどうかを判断するのは難しいに行く)。

私が言うことは、あなたがこれを動作させるかどうかということです。 OpenMPの仕様(他のスレッドモデルの大部分と同様)は、モデルがどのように「うまくいっているか」、あるいは「一緒にうまくいく」かどうかは言いません。たとえば、一部のOpenMP実装では基本的な実装にpthreadを使用していても、実装が何らかの作業をしなければ、ユーザーはpthreadsライブラリを直接呼び出してOpenMPと連動することはできません。現在の例はgcc bug 42616です(pthreadの中にあるOMPのループはクラッシュします)。もう1つの例はインテルであり、そのコンパイラは多くの並列モデルをサポートしていますが、それらを一緒に動作させるために努力しています。どのコンパイラを使用するのか分からないので、私が言うことができるのは小さなサンプルコードを試して、何か大きいことをする前に動作するかどうかを調べることです。

私は過去にこのようなことを試みました。私はpthreadを使ってOpenMPの構造を使っていました。私が見つけたのは、私のアプリケーションでは大丈夫でした。 OpenMP並列領域に遭遇したとき、各pthreadは最初のスレッドと見なされました。 OpenMPランタイムは、領域の追加スレッドを作成し、領域を実行しました。ほとんどのOpenMP実装はスレッドを破棄するのではなく、別の領域に遭遇したときに再利用するために空きプールに置くので、オーバーヘッドはうまく見えましたが、私はその領域で多くの作業を行いました。だからそれは動作することができます - しかし、あなたは注意する必要があります。

+0

ありがとうございます。したがって、あなたが非常に安全な側にいたいならば、OpenMPの構造はメインスレッドでのみ実行されるべきです。しかし、バグ報告から、私はそれがうまくいくはずで、何も禁止されています(少なくともgccではない)。 – tauran

関連する問題