2012-04-07 9 views
1

Iは、ネストされたループを有する:(L及びAが完全に定義された入力である)シーケンシャルバージョンとパラレルバージョンでは異なる結果が得られます - なぜですか?

#pragma omp parallel for schedule(guided) shared(L,A) \ 
    reduction(+:dummy) 
    for (i=k+1;i<row;i++){ 
      for (n=0;n<k;n++){ 
       #pragma omp atomic 
       dummy += L[i][n]*L[k][n]; 
       L[i][k] = (A[i][k] - dummy)/L[k][k]; 
      } 
      dummy = 0; 
    } 

そのシーケンシャルバージョン:

for (i=k+1;i<row;i++){ 
      for (n=0;n<k;n++){ 
       dummy += L[i][n]*L[k][n]; 
       L[i][k] = (A[i][k] - dummy)/L[k][k]; 
      } 
      dummy = 0; 
    } 

両者は異なる結果を与えます。また、パラレルバージョンはシーケンシャルバージョンよりもはるかに低速です。

何が問題が発生する可能性がありますか?

編集:

は原子ディレクティブによって引き起こされる問題を取り除くために、次のように私は、コードを変更:

#pragma omp parallel for schedule(guided) shared(L,A) \ 
    private(i) 
    for (i=k+1;i<row;i++){ 
     double dummyy = 0; 
     for (n=0;n<k;n++){ 
      dummyy += L[i][n]*L[k][n]; 
      L[i][k] = (A[i][k] - dummyy)/L[k][k]; 
     } 
    } 

をしかし、それはまた、問題がうまくいきませんでした。結果はまだ異なります。

+0

例えばそれは、スレッド固有でなければなりませんので、変数nは、OMPプラグマ内で宣言する必要がありますループ、:// stackoverflowの.com/a/8991640/893693 – inf

答えて

1

結果の違いは、スレッド間で共有される内部ループ変数nがompプラグマの外側で定義されているためです。

明確化: あなたは浮動小数点数で動作している場合は、このHTTPを読んfor (int n = 0;.....)

+0

それは私の問題を完全に解決しました。ありがとう! –

+0

@Lubo正しい方法は何ですか? –

2

私はOpenMPについてよく知らないけど、あなたの計算は順序に依存しないと思う。すなわち、内部ループの結果はL[i][k]に書き込まれ、ikは内部ループの不変量です。つまり、内部ループ中に同じ値がk回上書きされ、競合状態になります。

また、異なるスレッド間でdummyが共有されているように見えるので、プラグマパラメータが何らかの理由でそれを防止しない限り、そこに競合状態が存在する可能性があります。

私にとっては、シーケンシャル実行の場合と同じ結果が必要な場合は、内部ループの計算を同じ順序で実行する必要があります。したがって、外部ループのみを並列化することができます。

+0

私もそれについて考えました。しかし、これらのプラグマコマンドを使用すると、外部ループのみを並列化する必要があります。しかし明らかに、スレッド内で何か他のことが起こっているので、結果は同じではありません。 –

2

あなたの並列バージョンでは、不要な(そしておそらくは有害な)アトミック・ディレクティブを挿入しました。 dummyが削減変数になると宣言したら、OpenMPは縮小を妨げるスレッドを停止させます。私は不必要な指示の主な影響はコードを遅くすることだと思います。

結果が間違っているという別の回答があります。しかし、私はあなたがdummy0に設定しているように見えることがわかりました。これは、アウターループの繰り返しのそれぞれの終わりにあります。アキュムレータとして使用しようとすると奇妙に思えます。おそらく、内側のループ全体でdummyに減らしたいと思っていますか?

還元に問題がある場合read this

+0

私は実際には、内側のループを各スレッドで順番に実行したいと考えています。内側のループも分散していると私は今思っています。そうでなければ、これらの問題に苦しんでいません。 コードを少し修正しました。私はあなたが変更を見ることができるように編集しました。 –

関連する問題