2017-10-24 9 views
0

다음 코드를 사용하여 OpenMP 작업 구성을 사용하여 배열의 요소 합계를 찾습니다.
코드는 n = 10000까지 올바른 결과를 산출합니다.OpenMP 작업 - 더 큰 수의 반복에 대해 세그먼트 화 오류가 나타나는 이유는 무엇입니까?

하지만 그 외에는 세그먼트 오류가 발생합니다. gdb을 사용하여 reduce()에 대한 재귀 호출 중 하나에서 오류가 발생하는 것으로 나타났습니다. 입력 배열 할당에는 문제가 없으며이를 확인했습니다.

누구에게 문제가 있을지에 대한 제안이 있습니까?

int reduce (int *arr, unsigned long int n) 
{ 
    int x; 
    if (n <= 0) 
     return 0; 

    #pragma omp parallel 
    { 
     #pragma omp single nowait 
     { 
      #pragma omp task shared(x) 
      x = reduce(arr, n-1) + arr[n-1]; 
      #pragma omp taskwait 
     } 
    } 
    return x; 
} 
+3

'서명되지 않은'경우'n '은 (는)'<0'이됩니다. – yano

+0

스택 크기를 늘리고'OMP_STACKSIZE'를보십시오 – Gilles

+0

코드를 포맷하십시오. 이것은 너무 불필요하게 추악합니다. – Zulan

답변

2

함수 호출의 재귀 깊이를 통해 "스택 오버플로"가 발생하는 것 같습니다. 대부분의 openmp pragma는 tail-recursion optimization을 방해하는 함수 자체를 생성한다는 것을 기억하십시오.

valgrind를 통해 실행하는 경우 스택 오버플로에 대해 경고해야합니다.

+0

GCC 또는 Clang을 사용하는 경우'-fsanitize = address'를 사용하여 컴파일하고 링크 할 수도 있습니다. 그것은 프로그램을 계측하고 valgrind보다 비슷한 문제를 잡아낼 것이지만 조금 더 빠릅니다. –

1

dlasalle는 실제 오류에 대해서는 정확합니다.

그러나 OpenMP 작업을 사용하는 방법에 대한 두 가지 기본적인 문제가 있습니다. 각 재귀 호출 내에서 병렬 영역을 생성합니다. 즉, 중첩 된 병렬 영역을 사용합니다. 기본적으로 중첩 된 병렬 처리는 OpenMP에서 비활성화되어 있으며 여기서는 이해가되지 않습니다. 재귀 중에 스폰하는 모든 작업을 동일한 스레드 풀에서 실행하려고합니다. 이렇게하려면 parallel/single을 재귀 외부로 이동해야합니다 (예 : 이 세그 폴트하지 않을 경우에도

int reduce_par(int* arr, unsigned long int n) 
{ 
    int x; 
    if (n <= 0) 
     return 0; 
    #pragma omp task shared(x) 
    x = reduce_par(arr, n - 1) + arr[n - 1]; 
    #pragma omp taskwait 
    return x; 
} 

int reduce(int* arr, unsigned long int n) 
{ 
    #pragma omp parallel 
    { 
     #pragma omp single nowait 
     { 
      reduce_par(arr, n); 
     } 
    } 
} 

는, 당신은 무한한 메모리 대역폭없이 쓰레드 생성 오버 헤드 코어의 무한한 양을했다하더라도,이 여전히 병렬에서 어떤 성능 이점을 제공 woudn't. 이것을 파악하려면 작업과 작업의 그래프를 그리고 종속성을 추가하십시오. 작업 종속성을 고려한 시간 축에 그래프의 노드를 정렬하고 무엇이든 병렬로 계산할 수 있는지 확인하십시오.

병렬 합계에 대한 올바른 해결책은 reduce 절이있는 parallel for 작업 공유 구조입니다. 작업을 사용해야하는 경우 분할 및 정복을 사용해야합니다. 배열의 두 반쪽에 대해 두 개의 작업을 생성합니다. 합리적인 성능을 얻으려면 오버 헤드를 관리하기 쉽도록 최소한의 작업량으로 작업 작성/재귀를 중지해야합니다.