ループスレッドを安全にするために、ロックとクリティカルセクションをいじっています。コードは次のとおりです。
#pragma omp parallel for num_threads(4) private(k, f_part_k, len, len_3, mg, fact)
for (k = part+1; k < n; k++) {
/* Compute force on part due to k */
f_part_k[X] = curr[part].s[X] - curr[k].s[X];
f_part_k[Y] = curr[part].s[Y] - curr[k].s[Y];
len = sqrt(f_part_k[X]*f_part_k[X] + f_part_k[Y]*f_part_k[Y]);
len_3 = len*len*len;
mg = -G*curr[part].m*curr[k].m;
fact = mg/len_3;
f_part_k[X] *= fact;
f_part_k[Y] *= fact;
/* Add force in to total forces */
omp_set_lock(&(locks[k]));
//#pragma omp critical
{
forces[part][X] += f_part_k[X];
forces[part][Y] += f_part_k[Y];
forces[k][X] -= f_part_k[X];
forces[k][Y] -= f_part_k[Y];
}
omp_unset_lock(&(locks[k]));
}
for (i = 0; i < n; i++)
omp_destroy_lock(&(locks[i]));
}
コメント アウトされたクリティカル ディレクティブのみを使用すると、結果は良好です。つまり、シーケンシャル バージョンの結果と一致します。ただし、コードに示されているようにロックを使用すると、結果は大きく異なります。このロック アプローチを使用する私の理解では、force 配列への書き込みアクセスは安全でなければならないため、ロックの概念を誤解していると思います。正しい方向に私を向けることができますか?