2017-11-08 7 views
0

私はrun()という関数を持つプログラムを持っているとします。この関数はfor loopを実行し、内部でいくつかの処理を行います。OpenMP - パラレルでブロックするための複数の呼び出しを管理する

すべてのCPUコアを利用したいので、OpenMP#pragma omp parallel forを使用して並列化します。

さて、問題は、このrun()機能は、複数のスレッドから呼び出されていることであると同時に、run()を呼び出すスレッドの高い数があるときからOpenMP threadsがたくさんあるでしょうから、私は巨大なパフォーマンスの低下を持っています各parallel forプラグマコール。

はちょうど私がスレッド Aとスレッド Bを持っており、私のCPUは4つのコアを有する、ilustrateし、スレッド A呼び出しは for loopを実行するための4つの OpenMPスレッドを作成します run()は機能します。

今、同時に、スレッドBはまた、これが8つのOpenMPスレッドの合計をもたらす、より4つのOpenMPスレッドが生成され、run()呼び出します。上記の例では、OpenMPでこのバランスをとるためにいくつかの方法があるかどう

私の質問があり、OpenMPBためA半の半分のスレッドを使用することができます。 もう1つの戦略はOpenMPスレッドキューを作成することです。したがって、それ以上のスレッドを使用することはありませんOpenMPスレッド。

可能なことはありますか?

PS。私の例の2つのスレッドは、私のプログラムでは、スレッドの数が実行時に必要に応じて作成されるため、どれだけのスレッドがrun()を呼び出しているかは明確ではありません。私はおよそOpenMP作成されたスレッドを話している時はいつでも、私はOpenMPスレッドに呼ばれ、私はそれは単にスレッドと呼ばれる他の手段(例えばstd::thread)によって作成されたスレッドについて話しているときという

PS 2.注意。

答えて

0

あなたは、並列処理のためだけのOpenMPを使用して、あなたはnested parallelismあなたがスレッドの半分を使用するように指定するpragma omp parallelnum_threads引数を使用することができます有効にしている場合:

int const currentNumThreads = omp_get_num_threads(); 
int const maxNumThreads = omp_get_max_num_threads(); 
#pragma omp parallel for num_threads(maxNumThreads/currentNumThreads) 
for (...) { 
    ... 
} 

あなたが混在スレッド技術を使用している場合でも、 (あなたの場合のように思われる)、異なる方法を使用してcurrentNumThreadsmaxNumThreadsを設定することによっても、同じことを達成できます。

しかし、注意の言葉。入れ子にされた並列性を使用することは、コードがかなりfragile and rigidになるので、一般にOpenMPではお勧めできません。 run()関数への変更はどこから呼び出されたのかを意識する必要があり、今後のrun()への呼び出しでは、その内部のwhatsを認識する必要があります。パフォーマンスとメンテナンスの両面で、OpenMPの使用方法としてdata parallelのアプローチを実行しようとするのが最適です。つまり、各スレッドで、異なるチャンクのデータに対して同様の操作を実行します。

例外は、OpenMPタスクを使用している場合です。このタスクは起動でき、スケジューラに処理させることができます。並列forループでタスク並列性を使用すると、data localityの不足と、タスクが小さい場合の高いオーバーヘッドのためにパフォーマンスが低下する傾向があります。

+0

あなたが言ったように私の問題は混在したスレッド技術ですが、私は 'currentNumThreads'と' maxNumThreads'を手動で変更するとは思えません。同時に 'run()'を入力する保証はないからです。 私は、 'run()'とは何の関係も持た​​ない別のことをスレッドが持つことができ、 'num_threads()'の計算でカウントされることを意味します。 – Sassa

関連する問題