c++与OpenMP在n体模拟器中给出-非数字(nan)

C++ with OpenMP giving -not-a-numbers (nan) in N-Body Simulator

本文关键字:数字 nan OpenMP 模拟器 c++      更新时间:2023-10-16

我正在学习并行化,特别是OpenMP。我有一个连续的n体模拟器,它完美地工作并给出正确的输出,但是当我添加一个并行的for时,我所有的x,y位置输出为-nan。

在这个算法中没有竞争条件,并且parallel for创建了一个隐式屏障,所以如果我没有弄错的话(看起来我是错的),这应该可以工作。

当我在某些阶段输出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];
    }
}

指出:

  1. 我知道N线程不是最优的,但这只是练习的一部分
  2. 对于原型,我使用G = 1和所有质量= 1,这就是为什么我的公式可能看起来不正确

Gilles指出,解决方案是将局部变量设为私有。

#pragma omp parallel for num_threads ( N ) private( x_diff, y_diff, dist, dist_cubed )

是唯一需要修改的