2016-09-21 5 views
0

배열 종속성이있는 OpenACC 코드를 작성하고 있습니다. 내부 루프의 각 반복은 배열의 동일한 위치를 업데이트 할 수 있습니다. OpenACC에서OpenACC에서 배열 결과 결합

#pragma omp parallel private(i) 
    { 
      long unsigned int digit_local[d+11]; 
      for(i=0;i<d+11;i++) 
        digit_local[i] = 0; 

      #pragma omp for 
      for (i = 1; i <= n; ++i) { 
        long unsigned int remainder = 1; 
        for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) { 
          long unsigned int div = remainder/i; 
          long unsigned int mod = remainder % i; 
          digit_local[digit] += div; 
          remainder = mod * 10; 
        } 
      } 

      #pragma omp critical 
      for(long unsigned int digit = 0; digit < d+11; ++digit) 
        digits[digit] += digit_local[digit]; 

    } 

배열과 private 키워드 작동하지만 난 전역 배열과 민간 배열에 가입하는 방법에 아무 생각이 다음과 같이

long unsigned int digits[d + 11]; 
    for (long unsigned int digit = 0; digit < d + 11; ++digit) 
      digits[digit] = 0; 

    for (long unsigned int i = 1; i <= n; ++i) { 
      long unsigned int remainder = 1; 
      for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) { 
        long unsigned int div = remainder/i; 
        long unsigned int mod = remainder % i; 
        digits[digit] += div; // here 
        remainder = mod * 10; 
      } 
    } 

의 OpenMP 버전이 작성되었습니다 몇 가지 코드가있다.

감사합니다.

답변

0

OpenACC "원자 적 업데이트"지시어를 사용합니다.

  #pragma acc atomic update 
      digits[digit] += div; // here 

또는 OpenMP 버전과 비슷한 기능을 수행 할 수 있습니다.

long unsigned int digit_local[d+11][n]; 
    #pragma acc data create(digit_local) copyout(digits) 
    { 

    #pragma acc parallel loop gang vector 
    for (i = 1; i <= n; ++i) { 
      for(j=0;j<d+11;j++) digit_local[j][i] = 0; 
      long unsigned int remainder = 1; 
      for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) { 
        long unsigned int div = remainder/i; 
        long unsigned int mod = remainder % i; 
        digit_local[digit][i] += div; 
        remainder = mod * 10; 
      } 
    } 

    #pragma acc parallel loop gang 
    for(long unsigned int digit = 0; digit < d+11; ++digit) { 
      long unsigned int dsum = 0; 
      #pragma acc loop vector reduction(+:dsum) 
      for (i = 1; i <= n; ++i) { 
      dsum += digit_local[digit][i]; 
      } 
      digits[digit] = dsum; 
    } 
    } 

비록 이것이 어떤 속도 향상도 보이지 않을지 모르겠다.

도움이 되었으니 매트

+0

안녕 매트, 답장을 보내 주셔서 감사합니다. 이 지시어를 사용해 보았지만 성능이 향상되지 않았습니다 (같은 위치에 몇 가지 업데이트가 있음). –

+0

원자가가 비싸므로 속도가 향상되지 않는다는 것은 놀라운 일이 아닙니다. –

+0

답변 해 주셔서 감사합니다! –