openmp 共享和私有成员
openmp shared and private member
我正在尝试简单地将 MD 代码与 openmp 并行。但是,即使我将一个线程与 openmp 一起使用。结果不正确。如果我推荐了代码的 omp 部分,结果是正确的。我认为问题是在 omp 中错误地使用了共享变量和私有变量。谁能帮我解决这个问题?非常感谢你!代码如下
int i, j;
// parallelization using openmp
#pragma omp parallel shared(fx2,fy2,fz2,rx,ry,rz,N_molecular,L) private(i, j, xmin, ymin, zmin,rmin2, f)
{
#pragma omp for// reduction(+:fx2,fy2,fz2)
/*calculate all pair forces acting on each particles again*/
for(i = 0; i < N_molecular-1; i++){
for(j = i+1; j < N_molecular; j++){
xmin = rx[i] - rx[j] - L*round ((rx[i] - rx[j])/L);
ymin = ry[i] - ry[j] - L*round ((ry[i] - ry[j])/L);
zmin = rz[i] - rz[j] - L*round ((rz[i] - rz[j])/L);
rmin2 = xmin*xmin + ymin*ymin + zmin*zmin;
if(rmin2 < rcut*rcut)
{
f = 48./pow(rmin2,7) - 24./pow(rmin2,4);
//#pragma omp atomic update
fx2[i] += f*xmin;
//#pragma omp atomic update
fy2[i] += f*ymin;
//#pragma omp atomic update
fz2[i] += f*zmin;
//#pragma omp atomic update
fx2[j] = fx2[j] - f*xmin;
//#pragma omp atomic update
fy2[j] = fy2[j] - f*ymin;
//#pragma omp atomic update
fz2[j] = fz2[j] - f*zmin;
}
}
}
}
并行化此代码的棘手部分是确保力数组的更新不会产生竞争条件。在这里,当使用 i
索引时,不会出现任何问题,因为不同的线程将处理不同的 i
索引。但是,对于 j
索引而言情况并非如此,这足以阻止您使用此方法。
一种解决方案是将您的力存储在一些本地的每线程数组中,并在退出并行区域时将最终的单个结果累积到全局数组中。存在其他可能性,我在 .
中(我希望)详细描述了这些可能性
我正在尝试简单地将 MD 代码与 openmp 并行。但是,即使我将一个线程与 openmp 一起使用。结果不正确。如果我推荐了代码的 omp 部分,结果是正确的。我认为问题是在 omp 中错误地使用了共享变量和私有变量。谁能帮我解决这个问题?非常感谢你!代码如下
int i, j;
// parallelization using openmp
#pragma omp parallel shared(fx2,fy2,fz2,rx,ry,rz,N_molecular,L) private(i, j, xmin, ymin, zmin,rmin2, f)
{
#pragma omp for// reduction(+:fx2,fy2,fz2)
/*calculate all pair forces acting on each particles again*/
for(i = 0; i < N_molecular-1; i++){
for(j = i+1; j < N_molecular; j++){
xmin = rx[i] - rx[j] - L*round ((rx[i] - rx[j])/L);
ymin = ry[i] - ry[j] - L*round ((ry[i] - ry[j])/L);
zmin = rz[i] - rz[j] - L*round ((rz[i] - rz[j])/L);
rmin2 = xmin*xmin + ymin*ymin + zmin*zmin;
if(rmin2 < rcut*rcut)
{
f = 48./pow(rmin2,7) - 24./pow(rmin2,4);
//#pragma omp atomic update
fx2[i] += f*xmin;
//#pragma omp atomic update
fy2[i] += f*ymin;
//#pragma omp atomic update
fz2[i] += f*zmin;
//#pragma omp atomic update
fx2[j] = fx2[j] - f*xmin;
//#pragma omp atomic update
fy2[j] = fy2[j] - f*ymin;
//#pragma omp atomic update
fz2[j] = fz2[j] - f*zmin;
}
}
}
}
并行化此代码的棘手部分是确保力数组的更新不会产生竞争条件。在这里,当使用 i
索引时,不会出现任何问题,因为不同的线程将处理不同的 i
索引。但是,对于 j
索引而言情况并非如此,这足以阻止您使用此方法。
一种解决方案是将您的力存储在一些本地的每线程数组中,并在退出并行区域时将最终的单个结果累积到全局数组中。存在其他可能性,我在