6

友達、私はopenMPパラダイムを学ぼうとしています。プラグマの#ompを理解するために、次のコードを使用しました。

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;

}

上記のコードでは、#pragma omp parallelの最後に暗黙のバリアがあります。つまり、次のステートメントに進む前に、すべてのスレッド0、1、2、3、4がそこに到達する必要があります。

したがって、このバリアを確認するために、この「プラグマfor」を条件if(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がバリアをバイパスすることを意味します。驚いたことに、プログラムがハングし、すべてのスレッドがthread1を待機します。

そのような予期せぬ行動の説明を誰かに教えてもらえますか?ハングした最終コード:

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;

}

共有またはプライベートに設定してみましたが、プログラムの動作は変わりませんでした。

4

1 に答える 1

6

ここでの問題は、動作が標準で定義されていないことです。セクション2.5から、OpenMP 3.1仕様の21行目(ただし、テキストは最初からほぼ同じままです):

•各ワークシェアリングリージョンは、チーム内のすべてのスレッドが遭遇するか、まったく遭遇しない必要があります。

omp forワークシェアリング構造はどこにありますか。そうです、私も通常はコードがハングすることを期待しますが、コンパイラは、実行していることが決して起こらないと想定する権利があります。そのため、最終結果は、詳細によっては、ハングすることもあれば、起こらないこともあります。どのスレッドを保持するか-おそらくそれほど驚くことではありません。

于 2012-01-25T13:34:09.440 に答える