2015-01-18 4 views
0

OpenMP를 시작하기 만하면됩니다. 나는 외부 함수를 호출하는 for 루프에서 OpenMP 병렬을 실행할 수 있는지 궁금 해서요. 다른 함수를 호출하지 않습니다. 내 지점 수 있도록 일부 simplifed 코드에 넣어했습니다 : 내가 전화 몇 가지 더 추가 할 필요가 알고루프 용 OpenMP 내에서 함수 호출

#pragma omp parallel for 
for(span=0;span<info.nospanelement;span++) 
{ 
    some_function(info,wakePtr[time][span],P,w_ind,1); 

    //additions to be done each repeat 
    w_wake[0] += w_ind[0]; 
    w_wake[1] += w_ind[1]; 
    w_wake[2] += w_ind[2]; 
} 

을하지만,이 OpenMP의 루프는 기술적으로 작동 할 수 있습니까?

+1

를 "내가 몇 가지 오류 받고 있어요"어떤 오류가? – Borgleader

답변

2

당신은 결코 다른 스레드가 경쟁 조건을 방지 적절한 동기화없이 동일한 변수를 작성해야합니다.

프로그램에서

, 여러 스레드가 같은 값 변수의을 읽을 , 각 하나는 또 다른 가치를 추가 많은 계산을 덮어 쓸 수 있도록, 다음 모두 같은 위치에 결과를 작성하고 최종 결과에 추가하지 마십시오. 이 때문에 프로그램에 의해 계산 된 결과가 올바른 값보다 낮습니다 (그런데 ). 프로그램의 결과가 예상 한 결과와 어떻게 다른지 정확하게 기술해야합니다.). 따라서

#pragma omp parallel for 
    for(span=0;span<info.nospanelement;span++) { 
     some_function(info,wakePtr[time][span],P,w_ind,1); 

     //additions to be done each repeat 
#pragma omp atomic 
    w_wake[0] += w_ind[0]; 
#pragma omp atomic 
    w_wake[1] += w_ind[1]; 
#pragma omp atomic 
    w_wake[2] += w_ind[2]; 
} 

평행 합계를보다 효율적인 방법은 (해당 스레드에서 본) 전용 변수의 값을 누적 각 스레드를 가지고있다 :

간단하지만 비효율적 인 해결 방법은 원자 추가를 사용하는 부분합을 얻는다.

#pragma omp parallel 
{ 
    int wake0 = wake1 = wake2 = 0; // private variables 

    #pragma omp for 
    for(span=0;span<info.nospanelement;span++) 
    { 
     some_function(info,wakePtr[time][span],P,w_ind,1); 

     //additions to be done each repeat 
     wake0 += w_ind[0]; // accumulate in private variable 
     wake1 += w_ind[1]; 
     wake2 += w_ind[2]; 
    } 
// now we're out of the loop but still inside the parallel region 
// so, let's add up the partial sums 
#pragma omp atomic 
    w_wake[0] += wake0; 
#pragma omp atomic 
    w_wake[1] += wake1; 
#pragma omp atomic 
    w_wake[2] += wake2; 
} 

그것은 OpenMP를이 감소 작업을 관리해야하는 것이 좋습니다,하지만,하지만 당신은 배열에 결과를 저장해야하는 경우는 아마 쉽게는 자신이 방법으로 만 할 수 있습니다. 한편

, 당신이 정말로 다음 배열을 필요로하지 않는 경우에 당신은 단순히이 작업을 수행 할 수 있습니다

int wake0 = wake1 = wake2 = 0; // SHARED variables this time 
#pragma omp parallel for reduction(+ : wake0, wake1, wake2) 
{ 
    for(span=0;span<info.nospanelement;span++) 
    { 
     some_function(info,wakePtr[time][span],P,w_ind,1); 

     //additions to be done each repeat 
     wake0 += w_ind[0]; // accumulate in private variable 
     wake1 += w_ind[1]; 
     wake2 += w_ind[2]; 
    } 
} 
+0

OpenMP가 매우 녹슬 었습니다. 당신은'#pragma omp parallel for reduce (+ : w_wake [0], w_wake [1], w_wake [2])'를 할 수 없습니까? –

+0

@RafaelLerm 필자는 그렇게 생각했지만 어레이를 줄이는 것에 대해 봤는데, OpenMP 3.0에서 시작해서 Fortran을 제외하고는 OpenMP에서 그렇게 할 수 없었습니다. 아주 좋은 컴파일러였습니다. 또는 방금 인용 한 구문을 사용하여 수행 할 수도 있습니다. 시도하지 않고도 확신 할 수 없습니다. –

+0

확인. 이것은 포트란이 단지'max'와'min'을 줄이는 것에 대한 나의 모든 분노를 상기시켜줍니다. –