2013-10-29 2 views
1

그런 종류의 루프를 병렬 처리하려고합니다. 각 "calc_block"은 이전 반복에서 얻은 데이터를 사용합니다. OpenMP 병렬 루프

for (i=0 ; i<MAX_ITER; i++){ 

    norma1 = calc_block1(); 
    norma2 = calc_block2(); 
    norma3 = calc_block3(); 
    norma4 = calc_block4(); 

    norma = norma1+norma2+norma3+norma4; 
    ...some calc... 
    if(norma<eps)break; 
} 

나는이 tryed하지만, 속도 향상은 ~ 1.2

for (i=0 ; i<MAX_ITER; i++){ 
    #pragma omp parallel sections{ 
    #pragma omp section 
     norma1 = calc_block1(); 
    #pragma omp section 
     norma2 = calc_block2(); 
    #pragma omp section 
     norma3 = calc_block3(); 
    #pragma omp section 
     norma4 = calc_block4(); 
    } 

    norma = norma1+norma2+norma3+norma4; 
    ...some calc... 
    if(norma<eps)break; 
} 

내가 때문에 루프의 내부 섹션을 사용하는 오버 헤드의 일이 생각 매우 작다. 하지만 난 그걸 고치려면 어떻게 해야할지 모르겠어 ... 미리 감사드립니다!

+0

'MAX_ITER'의 값은 무엇입니까? 전체 코드와 각 블록의 절대 시간 비용은 각각 얼마입니까? – kangshiyin

답변

3

병렬 영역 내에서 전체 루프를 이동하면 오버 헤드를 줄일 수 있습니다. 따라서 팀을 구현하는 데 사용 된 풀의 스레드는 한 번만 "각성"합니다. 그것은 조금 까다 롭습니다 변수 공유 클래스의주의 깊은 고려가 포함됩니다

#pragma omp parallel private(i,...) num_threads(4) 
{ 
    for (i = 0; i < MAX_ITER; i++) 
    { 
     #pragma omp sections 
     { 
     #pragma omp section 
     norma1 = calc_block1(); 
     #pragma omp section 
     norma2 = calc_block2(); 
     #pragma omp section 
     norma3 = calc_block3(); 
     #pragma omp section 
     norma4 = calc_block4(); 
     } 

     #pragma omp single 
     { 
     norma = norm1 + norm2 + norm3 + norm4; 
     // ... some calc .. 
     } 

     if (norma < eps) break; 
    } 
} 

모두 sectionssingle 구조는 따라서 스레드가 다음 루프 반복에 가기 전에 동기화 할 자신의 끝에서 암시 적 장벽을 가지고 있습니다. single 구조는 이전에 프로그램의 일부분을 재생성합니다. private 절에있는 ... 부분에는 ... some calc ...과 관련된 변수 만 나열해야합니다. 공유 변수에 대한 액세스가 대부분의 OpenMP 구현에서 더 느리기 때문에 스레드 로컬 변수를 사용하여 직렬 부분을 실행하는 것이 좋습니다.

속도가 완전히 다른 이유로 완전히 선형이 아닐 수도 있습니다. 예를 들어 calc_blockX() (X은 , 2, 3 또는 4)은 계산 강도가 너무 낮을 수 있으므로 매우 높은 메모리 대역폭이 필요합니다. 메모리 서브 시스템이 동시에 4 개의 스레드 모두를 공급할 수 없다면, 속도 향상은 4보다 작을 것입니다. 이러한 경우의 예 - this question.

+0

나는 왜 당신이'flush'를 사용하는지 혼란스러워합니다. 내가 이해하는 바로는'single'은 exit시 암시 적'flush'를 호출하는 암시 적 장벽을 가지고 있으며 모든 공유 객체는'norma'를 포함하도록 동기화됩니다. 나는'flush'를 사용한 적이 없기 때문에 배울 점이 있습니다. –

+0

@redrum, 당신은'flush'의 사용에 대해 유효한 인수를 만들었습니다. –

+0

이 IBM Accodring [링크] (http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Fcompiler%2Fref%2Fruompflu.htm) (및 기타) 암시 적 플러시에 대해 "모든 공유 객체는 자동 저장 기간으로 액세스 할 수없는 객체를 제외하고 동기화됩니다." 문장의 마지막 부분은 "자동 저장 기간으로 접근 할 수없는 사람들을 제외하고"는 무엇을 의미합니까? 그건 좀 긴장 되네. –