2012-01-25 23 views
4

の友だち、私はopenMPパラダイムを学ぼうとしています。 プラグマの#ompを理解するために、次のコードを使用しました。#pragmaの最後の暗黙的なバリア

int main(void){ 
int tid; 
int i; 

omp_set_num_threads(5); 
#pragma omp parallel \ 
    private(tid) 
{ 
    tid=omp_get_thread_num(); 
    printf("tid=%d started ...\n", tid); 
    fflush(stdout); 

    #pragma omp for 
    for(i=1; i<=20; i++){ 
     printf("t%d - i%d \n", 
       omp_get_thread_num(), i); 
     fflush(stdout); 
    } 

    printf("tid=%d work done ...\n", tid); 
} 

return 0; 

}上記のコードで

は、に行く前にそこに到達しなければならないすべてのスレッド0,1,2,3,4を意味する、の#pragma OMP平行の終わりに暗黙的障壁が存在します次のステートメント

したがって、このバリアをチェックするために、(tid!= 0)という条件でこの「プラグマ」を囲みました。つまり、スレッド0以外のすべてのスレッド、つまり1,2,3,4がループ内で作業を完了する必要があります。 thread0を無期限に待ちます。しかし、私の驚いたことに、これは起こっていません。すべてのスレッドが反復を行い、正常に完了しています。すなわちt1は反復を完了する5,6,7,8 ---- t2は9,10,11,12 ---- t3は13,14,15,16を行い、t4は17,18,19,20を行う。注意:反復1,2,3,4は決して完了しませんでした。

tid!= 0の代わりに、同じ#pragma forをtid!= 1に囲み、thread0の代わりにthread1がバリアをバイパスします。私の驚いたことに、プログラムは現在ハングし、すべてのスレッドはスレッド1を待ちます。

誰かがこのような予期しない動作の説明を教えてください。絞首刑最終コード:

int main(void){ 
int tid; 
int i; 

omp_set_num_threads(5); 
#pragma omp parallel \ 
    private(tid) 
{ 
    tid=omp_get_thread_num(); 
    printf("tid=%d started ...\n", tid); 
    fflush(stdout); 

    if(tid!=1){ 
     /* worksharing */ 
     #pragma omp for 
     for(i=1; i<=20; i++){ 
      printf("t%d - i%d \n", 
       omp_get_thread_num(), i); 
      fflush(stdout); 
     } 
    }else{ 
     printf("t1 reached here. \n"); 
    } 

    printf("tid=%d work done ...\n", tid); 
} 

return 0; 

}

私が共有またはプライベートに設定しようとしたが、それは、プログラムの動作を変更しませんでした。

+0

#pragma omp forは、 "nowait"キーワードを使用してループの最後に暗黙のバリアを取り除く方法を提供しますが、私はそれを使用しませんでした。 –

+0

1) '私はプライベートである必要があります。 2)作業共有構造としての「omp for」は、すでに存在するスレッドに関する作業を共有する。スレッド1はワーク共有forループの実行のためにハングするので、自分自身をブロックします。 [work-sharing constructs](http://msdn.microsoft.com/en-us/library/y0x14tx2.aspx) – Bort

+0

マスタとワーカースレッドなどのチェックは、よりmpiまたはpthreadスタイルです。 openmpの背後にある考え方は、マスターと残りの人の間で行われているこのすべての行為を完全に取り除くことです。もちろん、これを行うことはできますが、別のスレッド間ではむしろdistutishishタスクを分離したいことがあります。 – Bort

答えて

5

ここでの問題は、動作が標準によって定義されていないことです。各ワークシェアリング領域は、チーム 中またはnoneにより、すべてのスレッドが遭遇しなければならない

:•セクション2.5、OpenMPの3.1 specification(ただし、テキストは初めから多かれ少なかれ同じに推移している)の21行からまったく。

ここで、omp forはワークシェアリングコンストラクトです。だから、私も通常あなたのコードでハングすることを期待していますが、コンパイラはあなたがやっていることは決して起こらないと仮定することができます。最終結果 - 時にはハングすることもありますが、あなたが抱えているスレッドは、おそらくそれほど驚くべきことではありません。

+1

リンクをありがとうございます。私もこれは未定義の動作をしていたが、実際にはopenMPライブラリの実際の実装を知っていたことは分かっていました。 「並列ブロックごとに1つの障壁しか実装されていないため、あるスレッドから別のスレッドへの信号伝達は、同じ並列ブロック内の異なる障壁を越えて機能します」 –

+3

とうまくいけば、「これからの私の学びは、次のようなものでした:「未定義の行動は、あらゆる種類の予期せぬ行動を引き起こすため、将来は使用しません。 – Bort

関連する問題