2016-11-07 38 views
2

我正在學習有關並行化的知識,尤其是OpenMP。我有一個順序的N-Body模擬器,它可以很好地工作並給出正確的輸出,但是當我添加一個並行模式時,我所有的x,y位置輸出爲-nan。OpenMP的C++在N-Body模擬器中給出了非數字(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]; 
    } 

} 

注:

  1. 我知道,N個線程是不是最佳的,但它只是行使
  2. 爲原型設計的一部分,我使用G = 1,所有羣衆= 1,這就是爲什麼我的公式可能看起來不正確
+0

你複製三分球'POS [i] = pos_new [I]'?那麼也許你應該交換指針,以便兩個矢量保持不同。 – LutzL

+0

將'private(x_diff,y_diff,dist,dist_cubed)'添加到您的'parallel'指令 – Gilles

+0

謝謝,我在睡了一個愉快的夜晚之後才意識到這一點。我不能標記你的答案是正確的,因爲這是一個評論! – cp420

回答

2

正如Gilles指出的,解決方案是使局部變量爲私有。

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

是唯一需要的變化

相關問題