OpenMP並列処理を使用する関数を記述したいが、並列領域内から呼び出されるかどうかにかかわらず動作するはずである。だから私は、並列処理を抑制するためにif
句を使用しますが、私は思ったので、これは動作しません:m
とs
:入れ子にされた並列領域を避ける
running func() serial:
m=1 s=1
running func() parallel:
m=16 s=16
はこのようにfunc()
への最初の呼び出しがうまく働いた出力を作成します
#include <omp.h>
#include <stdio.h>
int m=0,s=0;
void func()
{
bool p = omp_in_parallel();
// if clause to suppress nested parallelism
#pragma omp parallel if(!p)
{
/* do some massive work in parallel */
#pragma omp master
++m;
#pragma omp single
++s;
}
}
int main()
{
fprintf(stderr,"running func() serial:\n");
m=s=0;
func();
fprintf(stderr," m=%d s=%d\n",m,s);
fprintf(stderr,"running func() parallel:\n");
m=s=0;
#pragma omp parallel
func();
fprintf(stderr," m=%d s=%d\n",m,s);
}
値1を取得する必要がありますが、パラレル領域内からのfunc()
への2回目の呼び出しでは、これが抑制されていてもネストされた並列性(1スレッドごとに16チーム)が作成されました。つまり、omp master
とomp single
ディレクティブは、外側の並列領域ではなく、先行するomp parallel if(!p)
ディレクティブにバインドされます。 (コードを繰り返すことなくして)、それは、単一の関数内でこれを行うことは可能です等を定義することがもちろん
は、1次のコード
void work()
{
/* do some massive work in parallel */
#pragma omp master
++m;
#pragma omp single
++s;
}
void func()
{
if(omp_in_parallel())
work();
else
#pragma omp parallel
work();
}
ことで、この問題を修正することができますが、これは、追加の機能が必要?
はい、それは暗黙のうちに外部レベルでの並列処理がないことを一般的に保証することはできないので、それを暗に意味します。スレッドセーフな共有変数へのアクセスは、ミューテックス(ompのロック)のためのものです。とにかく、do_funcを呼び出す複数のスレッドがある場合、これらのスレッドの1つ(したがって呼び出し)だけをグローバル変数に書きたいと思っていますか?わかりませんあなたの特定のシナリオですが、それは非常に役に立つとは言えません。 – Grizzly