2012-04-07 4 views
1

나는 중첩 루프가 : (L 및 A는 완전히 입력 정의)순차 및 병렬 버전의 결과가 다릅니다 - 이유가 무엇입니까?

#pragma omp parallel for schedule(guided) shared(L,A) \ 
    reduction(+:dummy) 
    for (i=k+1;i<row;i++){ 
      for (n=0;n<k;n++){ 
       #pragma omp atomic 
       dummy += L[i][n]*L[k][n]; 
       L[i][k] = (A[i][k] - dummy)/L[k][k]; 
      } 
      dummy = 0; 
    } 

을하고 순차적 버전 : 그들은 모두 서로 다른 결과를

for (i=k+1;i<row;i++){ 
      for (n=0;n<k;n++){ 
       dummy += L[i][n]*L[k][n]; 
       L[i][k] = (A[i][k] - dummy)/L[k][k]; 
      } 
      dummy = 0; 
    } 

. 그리고 병렬 버전은 순차 버전보다 훨씬 느립니다.

무엇이 문제입니까?

편집 : 다음과 같이

이 원자 지시에 의해 발생하는 문제를 제거하기 위해, 나는 코드를 수정 :

#pragma omp parallel for schedule(guided) shared(L,A) \ 
    private(i) 
    for (i=k+1;i<row;i++){ 
     double dummyy = 0; 
     for (n=0;n<k;n++){ 
      dummyy += L[i][n]*L[k][n]; 
      L[i][k] = (A[i][k] - dummyy)/L[k][k]; 
     } 
    } 

을 그러나 그것은 또한 문제를 해결하지 않았다. 결과는 여전히 다릅니다.

+0

예를 들어,이 스레드 별해야하기 때문에 변수 n에서, OMP 프라그 내에서 선언되어야 루프 : // 유래 .com/a/8991640/893693 – inf

답변

1

결과의 차이점은 내부 루프 변수 n에서 발생합니다.이 변수는 스레드간에 공유되며 omp pragma 외부에서 정의되기 때문에 스레드간에 공유됩니다.

설명했습니다 : 부동 소수점 숫자에서 작동하는 경우,이 HTTP를 읽을 for (int n = 0;.....)

+0

그건 내 문제를 완전히 해결했습니다. 감사! –

+0

@ 루보 그래서 올바른 방법은 무엇입니까? –

2

저는 OpenMP에 익숙하지 않지만 계산이 순서에 독립적이지 않은 것으로 보입니다. 즉, 내부 루프의 결과는 L[i][k]에 기록되며, 여기서 ik은 내부 루프의 불변 조건입니다. 즉, 내부 루프 중에 동일한 값이 k 번 덮어 쓰여 경쟁 조건이 발생합니다.

더욱이 dummy은 다른 스레드간에 공유되는 것처럼 보이므로, pragma 매개 변수가 어떻게해서든지 그것을 막지 않으면 경쟁 조건이있을 수 있습니다.

내게있어, 순차적 실행에 의해 주어진 것과 같은 결과를 원한다면, 내 루프의 계산이 동일한 순차 순서로 수행되어야하는 것처럼 보입니다. 따라서 외부 루프 만 병렬 처리 할 수 ​​있습니다.

+0

나는 그것에 대해서도 생각했다. 그러나 이러한 pragma 명령을 사용하면 외부 루프 만 병렬 처리해야합니다. 그러나 분명히 결과는 동일하지 않으므로 스레드 내에서 다른 작업이 진행되고 있습니다. –

2

병렬 버전에서는 불필요한 원자력 지시문을 삽입했습니다. dummy을 감소 변수로 선언하면 OpenMP가 줄이기를 방해하는 스레드를 중지합니다. 불필요한 지시문의 주된 영향은 코드를 느리게하는 것입니다.

나는 당신이 결과의 잘못을 다루는 또 다른 대답을 가지고 있음을 알고 있습니다. 하지만 당신은 어떤 외부 유추 반복의 끝에서 dummy을 으로 설정하는 것으로 보이는데, 이는 감축 절이 제안하는 어떤 종류의 누적기로 사용하려고하면 이상하게 보입니다. 아마도 내부 루프에서 dummy으로 줄이고 싶습니까?

감소 문제가있는 경우 read this.

+0

실제로 내부 루프가 각 스레드에서 순차적으로 실행되기를 원합니다. 내부 루프가 분산되어 있다고 가정합니다. 그렇지 않으면 이러한 문제가 발생하지 않습니다. 코드를 약간 수정했습니다. 나는 당신이 그 수정을 볼 수 있도록 편집했다. –

관련 문제