2017-06-30 5 views
0

私は古いOpenMPの演習を少し練習しましたが、特にonのための解決策を見つけるのは難しいです。OpenMP依存グラフ

目標は、依存関係グラフに対応する最も単純なOpenMPコードを書くことです。

グラフがここに表示されている:http://imgur.com/a/8qkYb

最初のものは単純です。

これは、次のコードに対応:

#pragma omp parallel 
{ 
#pragma omp simple 
    { 
#pragma omp task 
    { 
     A1(); 
     A2(); 
    } 
#pragma omp task 
    { 
     B1(); 
     B2(); 
    } 
#pragma omp task 
    { 
     C1(); 
     C2(); 
    } 
    } 
} 

2つ目は、まだ簡単です。依存関係の数が、すべての関数呼び出し間で等しくないので、私にはかなりを盗聴されて

#pragma omp parallel 
{ 
#pragma omp simple 
    { 
#pragma omp task 
    { 
     A1(); 
    } 
#pragma omp task 
    { 
     B1(); 
    } 
#pragma omp task 
    { 
     C1(); 
    } 
#pragma omp barrier 
    A2(); 
    B2(); 
    C2(); 
    } 
} 

そして今、最後の1を付属しています... 。私はあなたが待っていなければならないタスクを明示的に述べるべきだと思ったが、OpenMPのドキュメントで探しているものが見つからない。

誰かがこの質問の説明をしていれば、私は今一ヶ月以上それを考えていたので、とても感謝しています。

答えて

0

まず、OpenMP 4.5仕様には#pragma omp simpleがありません。 あなたは#pragma omp singleを意味するものとします。

pragma omp barriersingle領域内の悪い考えである場合、コードを実行するスレッドは1つで、その領域を実行しない他のすべてのスレッドを待つためです。

さらに、2番目のA2では、B2とC2はタスクとして並列に実行されません。あなたのacutualの質問に

: あなたが探しているものは、タスクがOpenMP Secification pg. 169で構築するためにdepend句のようです。

depend節のかなり良い説明があり、Massimiliano for this questionの仕組みがあります。

0

あなたはそこに何が起こっているか理解すれば、最後の例では、その複雑ではありません:各タスクTnは、前の反復T-1_nとその近隣諸国(T-1_n-1T-1_n+1)に依存します。このパターンはJacobi stencilとして知られています。偏微分方程式ソルバでは非常に一般的です。

Henkersmannは、最も簡単なオプションは、OpenMPタスクのdepend句を使用している、言ったように:

int val_a[N], val_b[N];  
#pragma omp parallel 
#pragma omp single 
{ 
int *a = val_a; 
int *b = val_b; 
for(int t = 0; t < T; ++t) { 
    // Unroll the inner loop for the boundary cases 
    #pragma omp task depend(in:a[0], a[1]) depend(out:b[0]) 
    stencil(b, a, i); 

    for(int i = 1; i < N-1; ++i) { 
    #pragma omp task depend(in:a[i-1],a[i],a[i+1]) \ 
       depend(out:b[i]) 
    stencil(b, a, i); 
    } 

    #pragma omp task depend(in:a[N-2],a[N-1]) depend(out:b[N-1]) 
    stencil(b, a, N-1); 

    // Swap the pointers for the next iteration 
    int *tmp = a; 
    a = b; 
    b = tmp; 
} 
#pragma omp taskwait 
} 

ご覧の通り、OpenMPのタスク依存性は、ポイントツーポイントです、それはあなたがの面でそれらを表現することができないことを意味アレイ領域。

別のオプションは、この特定の場合のビットクリーナーは、バリアを使用して、間接的に依存関係を強制することである。

int a[N], b[N]; 
#pragma omp parallel 
for(int t = 0; t < T; ++t) { 
    #pragma omp for 
    for(int i = 0; i < N-1; ++i) { 
    stencil(b, a, i); 
    } 
} 

この第二の場合は、同期バリアを内部ループが終了するたびに行います。同期細分性は粗く、各外側ループの反復ごとに1つの同期ポイントしか持たないという意味でです。しかし、stencil機能が長く不均衡な場合は、おそらくタスクを使用する価値があります。

関連する問題