まず、外側のループの反復ごとに並列領域が再起動されるため、大きなオーバーヘッドが追加されます。
次に、スレッドの半分は何もせずに座っているだけです。これは、チャンク サイズが本来の 2 倍になっているためです。これnx/nthreads
は、並列ループの反復回数が であるため、合計でチャンクnx/2
が存在するためです。(nx/2)/(nx/nthreads) = nthreads/2
あなたが達成しようとしたことに加えて、の動作を複製することですschedule(static)
。
#pragma omp parallel
for (int t = 0; t < n; t++) {
#pragma omp for schedule(static)
for (int i = 1; i < nx/2+1; i++) {
for (int j = 1; j < nx-1; j++) {
T_c[i][j] = 0.25*(T_p[i-1][j]+T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]);
T_c[nx-i-1][j] = T_c[i][j];
}
}
#pragma omp single
copyT(T_p, T_c, nx);
}
print2file(T_c, nx, file);
copyT
parallel も使用するように変更する場合for
は、single
構成を削除する必要があります。default(shared)
これがデフォルトなので必要ありません。並列ループのループ変数を宣言しないでください。private
この変数が外側のスコープから来る場合でも (したがって、リージョン内で暗黙的に共有されます)、OpenMP は自動的にそれを非公開にします。ループ コントロールですべてのループ変数を宣言するだけで、デフォルトの共有ルールが適用されて自動的に機能します。
2 秒半後、(おそらく) 内部ループにエラーがあります。2 番目の割り当てステートメントは次のようになります。
T_c[nx-i-1][j] = T_c[i][j];
(またはT_c[nx-i][j]
下側にハローを保持しない場合)それ以外の場合、i
が等しい場合、の境界外にある which1
にアクセスすることになります。T_c[nx][...]
T_c
3 番目に、一般的なヒント: ある配列を別の配列にコピーする代わりに、それらの配列へのポインターを使用し、各反復の最後に 2 つのポインターを交換するだけです。