2012-11-09 2 views
1

저는 최근 Visual Studio에서 OpenMP를 실험하여 프로그램을 멀티 스레드하는 방법을 배우려고했습니다.Visual Studio를 사용하는 OpenMP : 경쟁 조건

나는 연속적으로이 코드를 실행하려고하면 :

내가 끝낼 무엇
int totalSum = 0; 

for(int x=0; x < 100; x++) 
{ 
    for(int y=0; y < 100; y++) 
    { 
     totalSum = totalSum + x + y; 
    } 
} 

은 그 totalSum =

나는 단순히 말에 의해 OpenMP의 기능을 추가하려고 990000 :

#pragma omp parallel for 
    for(int x=0; x < 100; x++) 
    { 

     for(int y=0; y < 100; y++) 
     { 
      totalSum = totalSum + x + y; 
     } 
    } 

결국 내가 으로 끝남 totalSum = 491293 또는 596865 또는 638260 등 ...

분명히 무슨 일이 일어나고 있는지는 경쟁 조건이 발생하고있는 것처럼 보입니다. 그리고 어떤 스레드가 totalSum에 먼저 액세스하는지에 따라 최종 답이 달라집니다.

내가 뭘 잘못하고 있니? x와 y는 private 변수로 올바르게 정의됩니다 (병렬 영역 내에서 생성되므로).

순차적으로 실행하는 것과 비교하여 프로그램을 멀티 스레딩 할 때 동일한 대답을 얻으려면 어떻게해야합니까?

+0

귀하의 경쟁 조건은 'totalSum'입니다 ... – Mysticial

답변

2

수정은 reduction 절을 사용하는 것입니다

int totalSum = 0; 

#pragma omp parallel for reduction(+:totalSum) // reduction 
for(int x=0; x < 100; x++) 
{ 

    for(int y=0; y < 100; y++) 
    { 
     totalSum = totalSum + x + y; 
    } 
} 

OpenMP를 감소 절에 최대 읽기를 그리고 당신은 어떻게 작동하는지 이해하게 될 것입니다.

+0

Thanks Mysticial. 나는 감소에 관해 읽었고, 그것이 중요한 지역이하는 것과 유사한 기능을 가지고있는 것처럼 보인다. – c0d3rz

+0

그것은 중요한 지역보다 훨씬 똑똑한 방법으로 그것을합니다. 실제로는 각 스레드에 총합의 로컬 복사본을 제공합니다. 그것들은 개별적으로 추가됩니다. 그런 다음 모든 스레드가 완료되면 최종 합계를 만들기 위해 로컬 합계를 더합니다. 이렇게하면 중요한 지역을 피할 수 있습니다. – Mysticial

+0

안녕하세요 신비로운 : 나는 더 많은 코드를 가지고 놀고 있었고 totalSum = x + y를 변경하면주의를 기울였습니다. 거기에 감축 절을 유지하면 OpenMP 출력이 직렬 실행과 일치하지 않는 또 다른 경쟁 조건이 발생합니다. 왜 그런 일이 일어 났는지 알아낼 수 없어요. 포인터 만주세요. – c0d3rz