2009-11-10 6 views
6

私はN-10からiのために、二つの機能、do_step_one(i)do_step_two(i)を持っています。OpenMPで途中のすべてのスレッドの同期化( `barrier`)を使って` omp parallel for`を作成する方法

現在、I本(シーケンシャル)コードを持っている:(do_step_one()do_step2()

for(unsigned int i=0; i<N; i++) { 
    do_step_one(i); 
} 

for(unsigned int i=0; i<N; i++) { 
    do_step_two(i); 
} 

各呼び出しは、任意の順序で並列に行うことができますが、任意のdo_step_two()が開始するすべてのdo_step_one()の終了を必要としますdo_step_one()の結果を使用します)。

#omp parallel for 
for(unsigned int i=0; i<N; i++) { 
    do_step_one(i); 

#omp barrier 

    do_step_two(i); 
} 

しかし、gccが文句

convolve_slices.c:21:警告:バリア領域が密接に命じ、ワークシェアリングの内側に重大な入れ子にすることはできません、

は、私は、次の試してみましたマスターまたは明示的なタスク領域。

私は何を誤解していますか?その問題を解決するには?

+0

あなたのOpenMPの構文が間違って見えます - あなたがあるように見えるの両方の呼び出しについて'#pragma'を見逃しました - あなたはそれを省略しましたか、それともそこにありませんか? –

+1

私はそれを省略します、申し訳ありませんが、実際のコードではここにあります。 –

答えて

4

一つの問題は、コードが仕様に準拠していないということです:)

あなたは最後まですべてdo_step_one()さんが必要な場合は、次のようなものが必要です:

#pragma omp parallel for 
for(unsigned int i=0; i<N; i++){ 
    do_step_one(i); 
} 

#pragma omp parallel for 
for(unsigned int i=0; i<N; i++){ 
    do_step_two(i); 
} 

これの結果は、第1の並列性と第2の並列性になります。

+0

私はOMPの仕事の大半を忘れています - この方法はまだスレッドを維持していますか、または2番目の 'parallel for'のために再作成する必要がありますか? –

+1

私はそれについては分かりません。内部実装の問題です。正式には、2番目のループのスレッドを再作成することができますが、最適化を回避することができます。 – Anna

+0

ああ、私は今どこに行っているのか分かっていると思う。第1のものはブロックごとに並列化されているので、第2のものを始めるために終わらなければならない。 特別なことは(おそらく効果がない)、2つのループの間に障壁を置くことが可能です。 – Anna

11

ただ、サイドノート、あなたは、スレッドが再作成されていないことを確認したい場合は、並行してのための宣言の宣言を分離:

#pragma omp parallel 
{ 
    #pragma omp for 
    for(unsigned int i=0; i<N; i++){ 
    do_step_one(i); 
    } 
    //implicit barrier here 
    #pragma omp for 
    for(unsigned int i=0; i<N; i++){ 
    do_step_two(i); 
    } 
} 
関連する問題