入れ子のforループを並列化するのに問題があります。コードは、この入れ子になったループを減らすためにompを使う
for(k = 0; k < m; k++) {
for(i = 0; i < k; i++) {
s = 0.0;
#pragma omp parallel for default(none) shared(i, k, q, m, n) private(j) reduction(+:s)
for(j = 0; j < n; j++) {
s += q[ i ][ j ] * q[ k ][ j ];
}
}
}
このコードの作品のようになりますが、「K」と「I」のループの下に何回ものスレッドを作成し、破棄する際によるオーバーヘッドのために非常に遅い実行されます。
理想的には私は、並列領域は一度だけ作成され、この
#pragma omp parallel default(none) shared(i, k, q, m, n, s) private(j)
for(k = 0; k < m; k++) {
for(i = 0; i < k; i++) {
s = 0.0;
#pragma omp for reduction(+:s)
for(j = 0; j < n; j++) {
s += q[ i ][ j ] * q[ k ][ j ];
}
}
}
ような何かをしたいです。しかし、私は間違った結果を得ています。私はこれが変数 's'が共有されているためだと思います。
's'を共有して引き続き削減を行う方法はありますか?
ありがとうございます!
P.S.以前の反復に依存するので、私は 'k'または 'i'ループを並列化できません。
並列化できる内部ループだけの場合は、並列化を高速化する可能性は低いです。余りにも計算が少なく、 'n 'が大きければメモリに束縛されます。 – Mysticial
ループの順序を変更しましたか?あなたのコードでは、 'k'と' i'のループの前に、 'j'のループを最初に置くことができます。これを行うと、q [k] [j]の値は 'i'以上のループの定数になるので、安全にループから抜け出します。 –
うん、ここではうまくいかないのは分かりません。各 'i'-iterationで' s'をリセットしていますか? –