OpenMPとIntelTBBを使用して、画像の畳み込みとlu分解を並列化しました。1〜8コアでテストしています。しかし、たとえばset_num_threads(1)とtask_scheduler_init InitTBB(1)をそれぞれ使用して1つのスレッドを指定することにより、OPenMPとTBBの1つのコアで試してみると、TBBのパフォーマンスは、TBBのオーバーヘッドのためにシーケンシャルコードと比較して若干の低下を示しますが、驚くべきことに、OpenMPはシングルコアでオーバーヘッドを示さず、シーケンシャルコードとまったく同じように動作します(Intel O3最適化レベルを使用)。OpenMPループの静的スケジューリングを使用しています。それは現実的ですか、それとも私は何か間違いをしていますか?
4 に答える
OpenMP ランタイムは、1 つのスレッドだけで実行すると、おそらくスレッドを作成しません。
また、OpenMP 並列化ディレクティブを使用するだけで、本質的にコンパイラにより多くの情報が提供されるため、シリアル コードの実行も高速になることがあります。たとえば、ワークシェアリング構造は、ループの反復が互いに独立していることをコンパイラーに伝えます。これは、コンパイラーが独自に推測できなかった可能性があり、コンパイラーがより積極的な最適化戦略を使用できるようにします。もちろん、常にではありませんが、「実際のコード」で発生するのを見てきました。
OpenMPは、コードの装飾された部分(#pragma omg for / parallel)をメインスレッド(OpenMPなしでも実行されます)と追加のスレッドにフォークします。
1つのスレッドのみを使用するように構成した場合、これはメインスレッドのみであり、OpenMPディレクティブがない場合と同じように実行されます。オーバーヘッドはありません。実行パスがフォークされなかったためです。
OpenMP は、コンパイラーがすべての作業を行うものです。コンパイラが常にシリアルコードになることを知っている場合、すべてのパラレルビットを完全にスキップできます。
私が理解しているTBBは、基本的には単なるライブラリです。アルゴリズムを並列およびシリアルで実行するために必要な部分で装飾する必要が常にあります。