2011-11-11 4 views
1

저는 Maxwell의 방정식을 C++로 풀기위한 과학 프로그램을 작성하고 있습니다. 데이터 병렬로 작업하고 OpenMP를 사용하여 프로그램을 병렬 처리하려고합니다. 그러나 OpenMP를 사용하여 for 루프를 병렬로 병렬 처리하면됩니다. 코드를 실행하면 프로그램이 SIGABRT를 얻습니다. 나는 잘못 알았다. 도와주세요. 다음과 같이 루프OpenMP를 사용하여 for 루프를 병렬로 만들 때 내 프로그램이 SIGABRT를 수신하는 이유는 무엇입니까?

은 다음과 같습니다

#pragma omp parallel for 

for (int i = 0; i < totalNoOfElementsInSecondMesh; i++) { 

    FEMSecondMeshElement2D *secondMeshElement = (FEMSecondMeshElement2D *)mesh->secondMeshFEMElement(i); 

    if (secondMeshElement->elementType == FEMDelectricElement) { 

     if (solutionType == TE) 
      calculateEzFieldForDielectricElement(secondMeshElement, i, currentSecondMeshIndex, nextFirstMeshIndex); 
     else 
      calculateHzFieldForDielectricElement(secondMeshElement, i, currentSecondMeshIndex, nextFirstMeshIndex); 

    } else if (secondMeshElement->elementType == FEMXPMLDielectricElement) { 

     if (solutionType == TE) 
      calculateEzFieldForDielectricPMLElement((FEMPMLSecondMeshElement2D *)secondMeshElement, i, currentSecondMeshIndex, nextFirstMeshIndex); 
     else 
      calculateHzFieldForDielectricPMLElement((FEMPMLSecondMeshElement2D *)secondMeshElement, i, currentSecondMeshIndex, nextFirstMeshIndex); 

    } 

} 

컴파일러는 기본적으로 엑스 코드 4.2와 함께 LLVM-GCC입니다.

도와주세요.

+0

혹시이 문제를 해결 했습니까? 사자, llvm-gcc 및 OpenMP와 같은 이상한 문제가 있습니다. – hanno

답변

1

라이온에서 컴파일러 문제가 발생할 가능성이 있습니다.

https://plus.google.com/101546077160053841119/posts/9h35WKKqffL

당신은 GCC 4.7이 해당 페이지의 링크에서 사자를 위해 미리 컴파일 다운로드 할 수 있습니다, 그것은 잘 작동하는 것 같다 :이 링크를 참조하십시오.

0

디버깅 및 모든 경고 (예 : -g -Wall 플래그)로 프로그램을 컴파일하려고 했습니까?

그런 다음 디버거를 사용하여 디버깅 할 수 있습니다.

+0

Xcode로 디버깅 중입니다. 내가 프로그램을 실행 해달라고 요청하면,이 SIGABRT 신호가 무작위로 나옵니다. 그것은 루프 변수 i에 대해 동일하지 않습니다. 모든 실행에서 i의 다른 값에서 신호를 얻습니다. for 루프에서 다른 함수를 호출 할 수 있습니까? –

+0

'core' 파일을 덤프하도록 요청할 수 없습니까 (예 : 쉘의'ulimit' 내장으로 적절한 제한값 설정). 사후 코어 덤프에'gdb'를 사용 하시겠습니까? –

0

프로그램이 충돌 가능성이 가장 높은 이유는 만약 절에 다른 기능이 그들에게 무엇을 따라 FEMSecondMeshElement2D * secondMeshElement, currentSecondMeshIndex 또는 nextFirstMeshIndex 접근 메모리 손상이다.

변수의 액세스를주의 깊게 확인하고 스레드를 개인적으로/공유에 적절하게 미리 선언하는 것이 좋습니다. 예 :

FEMSecondMeshElement2D *secondMeshElement = NULL; 

#pragma omp parallel for private(secondMeshElement) 
... 
+0

친애하는 Bort, 내가 볼 수 있듯이 for 루프 블록 내에서 메소드를 호출하고 있는데, mop 병렬 루프 전에 어떻게 변수를 선언해야합니까? 방법을 제안 해 주시겠습니까? –

+0

nextFirstMeshIndex는 현재 루프 외부에서 정의됩니다. 따라서 루프에 들어가면 모든 프로세스간에 공유됩니다. 이것이 각 스레드에 대한 개인 색인으로되어 있다면 내 대답과 같이 개인 pragma에 추가해야합니다. '#pragma omp parallel for private (secondMeshElement, nextFirstMeshIndex)'. 스레드 개인 메모리 할당을 할 필요가 있다면'pragma omp parallel'로 병렬 영역을 시작하고 필요한 로컬 메모리 할당을하고 루프에서'pragma omp for'를 호출 할 수 있습니다. – Bort

+0

둘 이상의 스레드에서 쓰는 경우 다음과 같이 vars를 생각하면 그렇지 않은 경우 비공개로 설정해야합니다. 그렇지 않으면 메모리 손상이 발생합니다. 스레드 개인은 각 스레드가 자신의 로컬 복사본을 가지고 있음을 의미합니다. 그 스레드 개인 변수의 반환 값이 필요하다면 반환 값의 배열 [size omp_get_num_threads()]를 사용하고 루프 이후의 결과를 줄이는 것이 좋습니다. 또는 룩을 줄이면됩니다. btw. i for the 루프는 기본적으로 자동으로 스레드 전용입니다. – Bort