2014-10-13 2 views
0

openmp에서 두 가지 다른 버전의 축소 기능을 사용하고 있으며 결과가 완전히 다릅니다. 다음 중 잘못된 것은 무엇입니까? openmp를 사용한 잘못된 축소

omp_set_num_threads(t);                       
    long long unsigned int d = 0;                     
    #pragma omp parallel for default(none) shared(some_stuff) reduction(+:d)    
    for (int i=start; i< n; i++)                 
    {                            
      d += calc(i,some_stuff);              
    }                            

    cout << d << endl; 

와 두 번째 버전

은 이것이다 :

omp_set_num_threads(t); 
    //reduction array 
    long long unsigned int* d = new long long unsigned int[t]; 
    for(int i = 0; i < t; i++) 
      d[i] = 0; 

    #pragma omp parallel for default(none) shared(somestuff, d) 
    for (int i=start; i< n; i++) 
    {                            
      long long unsigned dd = calc(i, somestuff); 
      d[omp_get_thread_num()] += dd; 
    } 

    long long unsigned int res = 0; 
    for(int i = 0; i < omp_get_num_threads(); i++){ 
      res += d[i]; 
    } 
    delete[] d; 

    cout << res << endl; 

답변

0

두 번째 코드는 잘못된 것입니다. omp_get_num_threads()은 병렬 영역 외부에서 호출 될 때 1을 반환하므로 코드가 모든 값을 최종 결과로 축소하지 않습니다. 명시 적으로 t로 스레드의 수를 해결하기 때문에, 당신은 대신 사용해야합니다

for(int i = 0; i < t; i++){ 
     res += d[i]; 
} 

또는, omp_get_max_threads()를 사용할 수 있습니다.

+0

@emab, 두 번째 접근법은 Hristo가 지적한 바와 같이 오류가 발생하는 것 외에도 허위 공유 때문에 제대로 수행되지 않습니다. –