2013-05-08 3 views
5

제목이 불명확하면 죄송합니다. 나는이 말을하는 방법을 모른다. 다음 작업을 수행 할 수있는 방법이 있는지OpenMP 반복 루프 병렬 영역

궁금 해요 :

#pragma omp parallel 
{ 
    for (int i = 0; i < iterations; i++) { 
     #pragma omp for 
     for (int j = 0; j < N; j++) 
      // Do something 
    } 
} 

같은 루프에 대한 민간 지정자를 생략하는 등의 일을 무시하고, 내 외부의 외부 스레드를 포크 할 수있는 방법이있다 루프를 사용하여 내부 루프를 병렬화 할 수 있습니까? 내 이해 (제발 내가 틀렸다면 정정 해주세요)에서 모든 스레드가 외부 루프를 실행합니다. 내부 루프의 동작에 대해서는 확신 할 수 없지만, for은 발생하는 각 스레드에 청크를 배포합니다.

내가 원하는 것은 외부 루프에서 iterations 번을 포크/조인 할 필요가 없지만 한 번만 수행하면됩니다. 이것이 올바른 전략인가?

병렬 처리하면 안되는 다른 외부 루프가 있다면 어떻게 될까요? 즉 누군가가 큰 응용 프로그램의 예에 나를 가리 키도록했다 내가 더 잘 OpenMP를 사용시 사용하는 전략을 이해할 수 있도록 OpenMP의를 사용하여 병렬 경우

#pragma omp parallel 
{ 

    for (int i = 0; i < iterations; i++) { 
     for(int k = 0; k < innerIterations; k++) { 
      #pragma omp for 
      for (int j = 0; j < N; j++) 
       // Do something 

      // Do something else 
     } 
    } 
} 

그것은 좋은 것입니다 .... 나는 아무 것도 찾을 수없는 것 같습니다.

설명 : 루프 순서를 변경하지 않거나 차단, 캐싱 및 일반적인 성능 고려 사항을 포함하는 솔루션을 찾고 있습니다. 루프 구조에서 OpenMP로이 작업을 수행하는 방법을 알고 싶습니다. // Do something은 의존성을 가질 수도 있고 가지지 않을 수도 있으며, 의존성이 있다고 가정하고 주위를 움직일 수는 없다고 가정합니다.

+0

아마도 당신이하고 싶은 것을 보여줄 수 있습니다. 나는 코드를 작성하는 것을 의미합니다 // 뭔가를하십시오 –

+0

@raxman, 그건 도움이되지 않습니다. 이것은 특정 문제에 대한 해결책이 아니라 그러한 문제에 대한 일반적인 해결책을 요구하기위한 것입니다. – Pochi

+0

당신은 앞으로 가서 어떤 대답을 upvote/accept 수 있습니다. 사람들이 약간의 노력을 기울이고 모든 것을위한 최소한의 upvotes를 얻은 것처럼 보입니다. –

답변

1

귀하의 질문에 답변 할 수 있는지 확실하지 않습니다. 나는 몇 달 동안 OpenMP를 사용 해왔다. 그러나 이와 같은 질문에 답하려고 할 때 나는 아래에 보여준 것과 같은 hello world printf 테스트를 수행한다. 나는 이것이 당신의 질문에 대답하는 데 도움이 될 것이라고 생각합니다. 또한 #pragma omp for nowait을 시도하고 어떻게되는지보십시오.

"// 무언가를하고 // 다른 작업을 수행하십시오"같은 메모리 주소에 쓰지 않고 경쟁 조건을 만들 때만 확인하십시오. 또한 많은 독서와 글을 쓰고 있다면 캐시를 효율적으로 사용하는 방법에 대해 생각할 필요가 있습니다.

#include "stdio.h" 
#include <omp.h> 
void loop(const int iterations, const int N) { 
    #pragma omp parallel 
    { 
     int start_thread = omp_get_thread_num(); 
     printf("start thread %d\n", start_thread); 
     for (int i = 0; i < iterations; i++) { 
      printf("\titeration %d, thread num %d\n", i, omp_get_thread_num()); 
      #pragma omp for 
      for (int j = 0; j < N; j++) { 
       printf("\t\t inner loop %d, thread num %d\n", j, omp_get_thread_num()); 
      } 
     } 
    } 
} 

int main() { 
    loop(2,30); 
} 

성능면에서 이와 같이 루프를 융합하는 것이 좋습니다.

#pragma omp for 
for(int n=0; n<iterations*N; n++) { 
    int i = n/N; 
    int j = n%N;  
    //do something as function of index i and j 
} 
0

정말 코드 내부의 의존성에 의존하기 때문에 대답하기가 어렵습니다. 그러나이 문제를 해결하는 일반적인 방법은 다음과 같이 루프의 중첩을 반전하는 것입니다

#pragma omp parallel 
{ 
    #pragma omp for 
    for (int j = 0; j < N; j++) { 
     for (int i = 0; i < iterations; i++) { 
      // Do something 
     } 
    } 
} 

꺼짐 물론, 이것은 또는 루프 내부의 코드 무엇인지 따라 가능하지 않을 수 있습니다.

3

2 개의 for 루프를 처리하는 방식이 내게 맞습니다. 원하는 동작을 달성한다는 의미에서 외부 루프는 병렬 처리되지 않고 내부 루프는 병렬 처리됩니다.더 무슨 명확히

, 난 당신의 코드에 몇 가지 메모를 추가 할 수 있습니다 :

#pragma omp parallel 
{ 
    // Here you have a certain number of threads, let's say M 
    for (int i = 0; i < iterations; i++) { 
     // Each thread enters this region and executes all the iterations 
     // from i = 0 to i < iterations. Note that i is a private variable. 
     #pragma omp for 
     for (int j = 0; j < N; j++) { 
      // What happens here is shared among threads so, 
      // according to the scheduling you choose, each thread 
      // will execute a particular portion of your N iterations 
     } // IMPLICIT BARRIER    
    } 
} 

암시 적 장벽 스레드가 서로 대기 동기화의 포인트입니다. 엄지 손가락의 일반적인 규칙에 따라 내부 루프이 아닌 외부 루프를 병렬 처리하는 것이 더 좋습니다 (위의 경우 iterations 포인트 대신). iterations*N 반복을위한 단일 동기화 지점이 생성됩니다.

+0

외부 루프는 일부 알고리즘의 다중 패스를 지정하기 때문에 병렬화 할 수 없습니다. 미안해. 미안. – Pochi

+0

바깥 쪽 루프는 작업 공유 지시문이 없으므로 병렬 처리되지 않습니다. – Massimiliano

+0

코드로 "hello world printf"테스트를 실행하면 모든 것을 보여줍니다. 장벽이 제거 된 현재 레이블을 추가하면 알 수 있습니다. 다른 말로하면 바깥 루프가 병렬 처리되지 않은 상태에서 루프가없는 상태입니다. –