2010-02-07 3 views
6

저는 OpenMP를 처음 사용하고 2D 배열의 각 항목을 처리하기 위해 개별 스레드를 시작하려고합니다. 그래서 본질적으로 OpenMP의 각 내부 루프에 대한 스레드 시작하기

이 :

#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic) 
    for (i = 0; i < dimension; i++) { 
     for (int j = 0; j < dimension; j++) { 
      a[i][j] = b[i][j] + c[i][j]; 

이 실제로 어떤 각 차원 항목에 대한 스레드를 시작하거나 않습니다

for (i = 0; i < dimension; i++) { 
    for (int j = 0; j < dimension; j++) { 
     a[i][j] = b[i][j] + c[i][j]; 

는 내가 일을하고있어이 무엇입니까? 어떻게 테스트 할 수 있겠습니까? 그것이 틀렸다면, 그것을하는 올바른 방법은 무엇입니까? 감사!

참고 : 코드가 크게 단순화되었습니다.

+0

당신이 사용하고있는 언어를 태그 할 수 있습니다 :

그래서 좀 2D 그리드를하고 (고정 된 4 × 4 스레드 그리드 예를 들어)에 대한 하나의 그리드의 모든 스레드를 시작하는 것 같아요 기존 태그 중 하나를 제거해야합니다. –

+0

좋은 점 mmyers - 참조 용으로 c/C++ (openMP는 c/C++ 및 fortran 만 사용)처럼 보입니다. –

답변

7

외부 루프 만 코드 샘플에서 병렬입니다. omp_get_thread_num()을 내부 루프에 인쇄하면 주어진 i에 대해 스레드 num이 동일하다는 것을 알 수 있습니다 (물론이 테스트는 다른 실행 결과가 달라 지므로 결정적이지 않습니다). 예를 들어,로 :

#include <stdio.h> 
#include <omp.h> 
#define dimension 4 

int main() { 
    #pragma omp parallel for 
    for (int i = 0; i < dimension; i++) 
     for (int j = 0; j < dimension; j++) 
      printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num()); 
    } 

내가 얻을 :

i=1, j=0, thread = 1 
i=3, j=0, thread = 3 
i=2, j=0, thread = 2 
i=0, j=0, thread = 0 
i=1, j=1, thread = 1 
i=3, j=1, thread = 3 
i=2, j=1, thread = 2 
i=0, j=1, thread = 0 
i=1, j=2, thread = 1 
i=3, j=2, thread = 3 
i=2, j=2, thread = 2 
i=0, j=2, thread = 0 
i=1, j=3, thread = 1 
i=3, j=3, thread = 3 
i=2, j=3, thread = 2 
i=0, j=3, thread = 0 

이 코드의 나머지 부분에 관해서는, 당신은 새로운 질문에 자세한 내용을 넣어 할 수 있습니다 (이것은 작은 샘플에서 이야기하기는 어렵습니다), 예를 들어, j이 나중에 선언 될 때 private(j)을 넣을 수 없습니다. 위의 예에서 자동으로 비공개입니다. 나는 diff이 우리가 샘플에서 볼 수없는 변수라고 생각한다. 또한, 루프 변수 i 자동 비공개합니다 (version 2.5 spec에서 - 3.0 사양에 동일한)

반복 변수 용 루프 구조물 용에 대한 또는 병렬 루프가 구조체의 비공개 .

편집 : 위의 내용은 본인과 내가 작성한 코드에 대한 것이지만 아래 내용을 참조하십시오. OpenMP 버전 3.0 (예 : gcc version 4.4에서 사용할 수 있지만 버전 4.3은 사용할 수 없음)에는 코드를 작성할 수있는 코드가있는 #pragma omp parallel for collapse (2)을 사용하여 루프 용으로 두 병렬화를 수행합니다 (the spec 참조).

편집는 :

i=0, j=0, thread = 0 
i=0, j=2, thread = 1 
i=1, j=0, thread = 2 
i=2, j=0, thread = 4 
i=0, j=1, thread = 0 
i=1, j=2, thread = 3 
i=3, j=0, thread = 6 
i=2, j=2, thread = 5 
i=3, j=2, thread = 7 
i=0, j=3, thread = 1 
i=1, j=1, thread = 2 
i=2, j=1, thread = 4 
i=1, j=3, thread = 3 
i=3, j=1, thread = 6 
i=2, j=3, thread = 5 
i=3, j=3, thread = 7 

댓글 here (검색 : OK, 지금 병렬 내부 루프를 보여주는, 다음과 같은 출력을 얻을 수 collapse (2)를 사용하여 GCC 4.5.0을 다운로드하고 위의 코드를 실행하지만, "해결 방법")은 두 루프를 병렬 처리하려는 경우 버전 2.5의 해결 방법에도 해당되지만 위의 버전 2.5 사양은 매우 명확합니다 (섹션 A.35의 비 규격 예 참조).

+0

감사합니다. 붕괴가 내가 찾고있는 트릭이었습니다! – achinda99

0

중첩 된 omp parallel fors (omp_set_nested(1) 호출 이후)를 사용할 수는 있지만 모든 openmp 구현에서 지원되지는 않습니다.하지만,

#pragma omp parallel for 
for(k = 0; k < 16; k++) 
{ 
    int i,j,i_min,j_min,i_max,j_max; 
    i_min=(k/4) * (dimension/4); 
    i_max=(k/4 + 1) * (dimension/4); 
    j_min=(k%4) * (dimension/4); 
    j_max=(k%4 + 1) * (dimension/4); 

    for(i=i_min;i<i_max;i++) 
     for(j=j_min;j<j_max;j++) 
     f(i,j); 

} 
관련 문제