2011-09-04 14 views
2

私はOpenMPとインテルTBBを使用してイメージ畳み込みとlu分解を並列化しました。私は1〜8のコアでそれをテストしています。しかし、OPENMPとTBBの1つのコアで、set_num_threads(1)とtask_scheduler_init InitTBB(1)を使って1つのスレッドを指定すると、 TBBのパフォーマンスは、TBBのオーバーヘッドによりシーケンシャルコードに比べていくらか小さな劣化を示しますが、驚くべきことにOpenMPはシングルコアのオーバヘッドを示さず、シーケンシャルコードと正確に等しく(インテルO3最適化レベルを使用して)私はOpenMPループの静的スケジューリングを使用しています。現実的ですか、私は間違いをしていますか?OpenMPオーバーヘッド

+0

'num_threads'から' set_num_threads(num_threads) 'までの引数が実行時にのみ、つまりユーザー入力からしかわからない場合、これも起こりますか? – Walter

答えて

0

OpenMPは、コンパイラがすべての作業を行う場所です。コンパイラがシリアルコードになることがわかっている場合、常に並列ビットのすべてをスキップすることができます。

TBB基本的に単なる図書館です。あなたのアルゴリズムにパラレルでもシリアルでも実行するために必要な部分が装飾されている必要が常にあります。

+0

OpenMPでシングルスレッドを設定すると、OpenMPプラグマをスキップしてシリアルに実行できるほどインテリジェントに実装されているといえますか? –

+0

あなたの質問からコンパイル時にそれを設定した場合、私はそれが可能であると思われます。 – Flexo

+0

set_num_threads(1)はOpenMPライブラリの一部であり、OpenMPコンパイラ指令ではないため、コンパイラによってスキップされません。 – DirkMausF

2

OpenMPランタイムは、スレッドを1つだけ実行すると、スレッドを作成しない可能性があります。

また、OpenMP並列化ディレクティブを使用すると、というコードでも、本質的にコンパイラに詳細情報を与えているように、シリアルコードがより速く実行されます。例えば、ワークシェアリング構成は、ループの反復が互いに独立していることをコンパイラに伝えます。ループの反復はそれ自身では推測できず、より積極的な最適化戦略を使用することができます。もちろん、必ずしもそうではありませんが、私は「実世界のコード」でそれが起こるのを見ました。

+1

"OpenMPの並列化命令は、本質的にコンパイラーにもっと情報を与えているように、より速く走る」 - これは興味深いことです。残念ながら、openmpプラグマで1つのスレッドを使用しているときにわずかなパフォーマンスの低下が見られましたが、1つのスレッドしか存在しない場合は#ifdefsを使用していました。あなたはこれを特定のコンパイラ/コードの組み合わせで観察しましたか? – Sayan

+0

うわー、聞いたこともありません。それを試さなければならない。面白い! – DirkMausF

0

OpenMPはコードの装飾部分(#pragma omg for/parallel)を(OpenMPなしで実行される)メインスレッドと追加のスレッドにフォークします。

1つのスレッドのみを使用するように設定した場合、これはメインスレッドであり、OpenMPディレクティブなしで実行されます。オーバーヘッドがなく、実行パスが分岐しなかったためです。

0

OpenMPについてのことは、コンパイラがあなたのために仕事をしていることです。シーケンシャルコードを最小限に変更する必要があり、各スレッドに与えられたタスクがかなり大きい場合は、 PthreadやC++ 11のスレッドを使ってコードをテストし、その結果を見てみることをお勧めします。