2012-11-27 2 views
0

OpenMP가 중첩 루프와 함께 작동하는 방식을 이해하는 데 문제가 있습니다. 도와주세요! 이 코드는 (난 그냥 운에 의해 그것을 가지고) 어떻게 작동하는지 아주 확실하지 않다, 그러나OpenMP Nested Loop, 코드는 무엇을하고 있습니까?

#pragma omp parallel private(i) 
{ 
for(i=0; i<n; i++) 
{ 
    #pragma omp for 
    for(j=0; j<n; j++) 
    { 
     if(asubsref(seed,j) > 0) 
      asubsref(bin,j) = asubsref(bin,j) + 1; 
    } 
    #pragma omp for 
    for(j=0; j<n; j++) 
     asubsref(seed,j) = asubsref(seed,j) - asubsref(w,i); 
} 
} 

:

나는 병렬로 실행하려면 다음 코드를 얻었다. 다음은 내가 생각하는 바가 무엇인지 ...

그래서 for(i=0; i<n; i++)은 다른 스레드로 분리되어 병렬로 실행됩니다. iprivate으로 선언되었으므로 루프의 각 인스턴스는 "샌드 박스 처리"됩니다. 즉, j에 대한 변경 사항은 해당 스레드에 남아 있습니다 (적어도 모든 스레드가 완료 될 때까지). 나는 #pragma omp for을 선언하지 않으면 코드가 깨어지기 때문에 혼란 스럽습니다 ... 왜 이것이지 모르겠습니다.

누군가이 코드가 수행하는 것을 통해 나를 걸을 수 있으면 대단히 감사하겠습니다. 고맙습니다!

+0

http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Fcompiler%2Fref%2Fruompfor.htm – imreal

답변

2

이것은 여러 입력의 오버 헤드를 줄이기 위해 일반적으로 수행하며 병렬 영역을 오가며 출력합니다. 다음 해당 코드에 질문의 코드를 비교 :

for (i=0; i<n; i++) 
{ 
    #pragma omp parallel for 
    for (j=0; j<n; j++) 
    { 
     if (asubsref(seed,j) > 0) 
      asubsref(bin,j) = asubsref(bin,j) + 1; 
    } 
    #pragma omp parallel for 
    for (j=0; j<n; j++) 
     asubsref(seed,j) = asubsref(seed,j) - asubsref(w,i); 
} 

그것은 in 배 이상 외부 루프를 실행합니다. 외부 루프의 각 반복에서 j 이상의 두 병렬 루프를 실행하고 스레드간에 n 반복을 분할합니다. 여기서 문제는 두 개의 평행 한 영역이 내부에 있고 각각이 활성화되어 있다는 것입니다. n 번. 이로 인해 특정 간격의 값인 n에 상당한 오버 헤드가 추가 될 수 있습니다 (실제 간격은 여러 요인에 따라 달라질 수 있음).

오버 헤드를 줄이기 위해 전체 코드를 병렬 영역에 넣습니다. 따라서 각 스레드는 외부 루프의 모든 반복을 실행하고 내부 반복은 여전히 ​​스레드간에 분할됩니다. 작업 공유 구성을 제거하면 내부 루프가 스레드간에 분산되지 않습니다. 대신 각 스레드는 내부 반복의 전체 범위를 모두 실행하므로 예를 들어 asubsref(bin,j)은 한 번만이 아니라 num_threads 번까지 증가합니다 (왜 "최대"힌트 : 비보호 동시 데이터 액세스)?

대부분 병렬 구조 내에서 외부 루프를 실행하는 경우 동일한 반복에서 계속 똑같이 다른 스레드를 유지하려고합니다. 이것은 루프 본문의 마지막에 장벽에 의해 얻을 수있는 다음 for 작업 공유 구조가 마지막에 암시 적 장벽이 있기 때문에 귀하의 경우에는

#pragma omp parallel private(i) 
{ 
    for (i = 0; i < n; i++) 
    { 
     ... 
     #pragma omp barrier 
    } 
} 

명시 적 장벽이 필요하지 않습니다.

+0

자세한 답변 해 주셔서 감사합니다. ! '#pragma omp for'는 지금 무엇을하는지 이해하지만, 가장 외부의 'for' 루프가 쓰레드간에 어떻게 분산되어 있습니까? 모든 스레드가 외부 루프를 실행하는 것처럼 보입니다 (동일한 코드가 두 번 이상 실행됨을 의미). 각 쓰레드가'for' 루프를 한 번 반복하면 ('#pragma omp for'처럼)? 내 질문은 : 왜 우리는 가장 바깥 쪽 루프에 대한 #pragma omp for를 필요로하지 않는가? (우리가 코드를 넣으면 코드가 실패 하는가?) – pauliwago

+0

외부 루프가 분산되지 않는다. 각 스레드는 모든 범위의 반복을 실행합니다. 아마도 연속 반복간에 데이터 종속성이있을 수 있습니다. –

+0

모든 스레드가 반복의 전체 범위를 실행하는 경우 컴퓨터가 느려지지는 않습니까? – pauliwago

관련 문제