我正在研究并行化,尤其是OpenMP。我有一个顺序的N-Body模拟器,可以很好地工作并提供正确的输出,但是当我添加一个并行的时,我所有的x,y位置输出为-nan。
此算法中没有竞争条件,而并行用于创建隐式屏障,因此如果我没有弄错(这看起来是我的话),这应该有效。
当我在某些阶段输出new_pos
时,我开始得到像64.4358358.53这样的数字。我不明白这样的数字是如何存在的,更不用说由计算机代表了。
关于是什么导致他们的任何想法?
for( int t = 0; t < TOTAL_STEPS; ++t )
{
#pragma omp parallel for num_threads( N )
for( int q = 0; q < N; ++q )
{
forces[q][X] = forces[q][Y] = 0;
for( int k = 0; k < N; ++k )
{
if( q == k ) continue;
x_diff = pos[q][X] - pos[k][X];
y_diff = pos[q][Y] - pos[k][Y];
dist = sqrt( x_diff * x_diff + y_diff * y_diff );
// performing a calculation with a distance this small introduces
// small denominator errors
if( dist > 0.01 )
{
dist_cubed = dist * dist * dist;
forces[q][X] -= 1 / dist_cubed * x_diff;
forces[q][Y] -= 1 / dist_cubed * y_diff;
}
else continue;
}
pos_new[q][X] = pos[q][X] + vel[q][X] * timestep;
pos_new[q][Y] = pos[q][Y] + vel[q][Y] * timestep;
vel_new[q][X] = vel[q][X] + ( forces[q][X] * timestep );
vel_new[q][Y] = vel[q][Y] + ( forces[q][Y] * timestep );
}
for( int i = 0; i < N; ++ i )
{
pos[i] = pos_new[i];
vel[i] = vel_new[i];
}
}
注意:
答案 0 :(得分:2)
正如吉尔斯指出的那样,解决方案是将局部变量设为私有。
#pragma omp parallel for num_threads ( N ) private( x_diff, y_diff, dist, dist_cubed )
是唯一需要的更改