2016-11-07 5 views
2

저는 병렬화와 특히 OpenMP에 대해 배우고 있습니다. 필자는 완벽하게 작동하고 올바른 출력을 제공하는 순차적 N 몸체 시뮬레이터를 가지고 있지만 병렬로 추가하면 모든 x, y 위치가 -nan으로 출력됩니다.N-Body Simulator에서 OpenMP로 -not-a-numbers (nan)를 제공하는 C++

이 알고리즘에는 경쟁 조건이 없으며 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]; 
    } 

} 

참고 : 나는 G = 1 모든 대중 = 1을 사용하고,

  1. 나는 N 스레드가 최적이 아닌 것을 알고 있지만 운동 프로토 타입
  2. 의 한 부분이었다 내 수식이 올바르지 않게 보이는 이유입니다.
+0

당신이 포인터를 복사하는 유일한 필수 변경했다? 그런 다음 두 벡터가 서로 달라 지도록 포인터를 바꿔야합니다. – LutzL

+0

'parallel' 지시어에'private (x_diff, y_diff, dist, dist_cubed)'를 추가하십시오. – Gilles

+0

감사합니다. 비록 이것이 의견이지만 올바른 답변을 표시 할 수 없습니다! – cp420

답변

2

Gilles가 지적했듯이 해결 방법은 로컬 변수를 비공개로 설정하는 것입니다. `;

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

는`POS [I] = pos_new [I]에서