問題は、あなたの内側のループは、例えば、以下の二つの文が並行して起こる可能性があり、書き込み競合状態を持っているので、ということです:コードは行ごとに沸く何
Output[42] = Output[42] + staticConstant[9] * data[42-9];
Output[42] = Output[42] + staticConstant[19] * data[42-19];
は次のとおりです。
Load O[42] to R1
Load C[] to R2
Add R2 to R1
Store R1 to O[42]
しかし、paralleliserは次のように実行しているコードにつながる可能性:
Load O[42] to R1
Load O[42] to R3
Load C[9] to R2
Load C[19] to R4
Add R2 to R1
Add R4 to R3
Store R1 to O[42]
Store R3 to O[42]
ご覧のとおり、2つのLoad O[42]
行は、C[9]
またはC[19]
を追加する前に値をロードするので、最初の計算は実質的に無視されます。
最も簡単な修正は次のとおりです。唯一の内側のループが並列化されるよう
for (int i = 0; i <500; i++)
{
#pragma omp parallel for
for (j=i; j < 102342; j++)
{
Output[j] += staticConstant[i] * data[j-i];
}
}
は今何の競合状態は存在しません。
ありがとうございます。<3ループでリダクションを使用するにはどうすればよいですか?私はopenmpの古いバージョンを使用しているので、私はそれをオーバーロードできません。 – StephanieLoves
他のオプションは、2つのループを交換することです。 'j'ループはより多くの反復を持つので、最も外側のループを並列化することでオーバーヘッドが少なくなります。 –