2014-03-24 4 views
-1
#pragma omp parallel for schedule(static) default(none) 
for(int row = 0; row < m_height; row++) 
{ 
    for(int col = 0; col < m_width; col++) 
    { 
     int RySqr, RxSqr; 

     SettingSigmaN(eta, m_RxInitial + col, m_RyInitial + row , RxSqr, RySqr); 

     FunctionUsing(RySqr,RxSqr); 
    } 
} 

void CImagePro::SettingSigmaN(int Eta, int x, int y, int &RxSqr, int &RySqr, int &returnValue) 
{ 
    int rSqr = GetRadius(x,y,RxSqr,RySqr); 
    returnValue = GetNumberFromTable(rsqr); 
} 


int CImagePro::GetRadius(int x, int y, int &RxSqr, int &RySqr) 
{ 
    if (x == m_RxInitial) 
    {  
     RxSqr = m_RxSqrInitial; 
     if (y == m_RyInitial) 
     { 
      RySqr = m_RySqrInitial; 
     } 
     else if (abs(y) % 2 == abs(m_RyInitial) % 2) 
     { 
      RySqr = RySqr + (y<<2) + 4; //(y+2)^2 
     } 
    } 
    else 
    { 
     RxSqr = RxSqr + (x << 1) + 1; //(x+1)^2 
    } 
    return clamp(((RxSqr+RySqr)>>RAD_RES_REDUCTION),0,(1<<(RAD_RES-RAD_RES_REDUCTION))-1); 
} 

ok 여기 내 코드가 있으며 내 문제는 GetRadius 함수 안에 있습니다. 나는 많은 스레드가 각 스레드가 x, y의 다른 위치에서 시작하기 때문에. 그러나 나는 정말로 GetRadius() 내부의 버그가 어디인지 이해하지 못한다.방사형 계산을 사용하는 openmp 버그

아마도 RySqr 계산이라고 생각했습니다. 디버깅 할 수있는 방법을 제안 해 주시겠습니까? 또는 내 문제를 볼 수 있습니까?

업데이트 :이 다른 스레드 사이의 점프가 왜 난 아직도 정말 이해가 안 :

이 내 코드의 대부분을 고정했다.

int CImagePro::GetRadius(int x, int y, int &RxSqr, int &RySqr) 
    { 
    if (x == m_RxInitial) 
    {  
     RxSqr = m_RxSqrInitial; 
    } 
    else 
    { 
     RxSqr = x * x; 
    } 

    if (y == m_RyInitial) 
    { 
     RySqr = m_RySqrInitial; 
    } 
    else if (abs(y) % 2 == abs(m_RyInitial) % 2) 
    { 
     RySqr = y * y; 
    } 
    return clamp(((RxSqr + RySqr) >> RAD_RES_REDUCTION), 0, (1 << (RAD_RES - RAD_RES_REDUCTION)) - 1); 
} 

답변

1

이 일을 컴파일하면 정말 궁금해? default(none)을 지정하지만 클래스의 데이터 멤버를 일관되게 사용합니다. 그들은 모두 정체입니까?

당신이 할 수있는 일은 default(shared)을 의미하는 을 남겨두고, ii) 명시 적으로 공유하여 값에 대한 공유 액세스 권한을 부여하거나, iii) 병렬 영역 내에서 사용하는 변수를 초기화하여 각 스레드 예를 들어 p_RxInitial 등으로 불리는 m_RxInitial 등의 개인 사본이 있습니다. 첫 번째 옵션은 거의 문제를 일으킬 수 있습니다.

다음 옵션 II)을 보여

1) 통과해야 헬퍼 클래스 포함한 모든 확인을, 당신을 위해이 멤버 함수에서

struct ShareData{ 
    int s_RxInitial 
    /* ... */ 
} 

2) 이전에, 병렬 섹션을 포함 할 수 병렬 루프

ShareData SD; 
SD.s_RxInitial = m_RxInitial; 
/* ... */ 

3)는 평행 부에 보내기 정의

,536,
#pragma omp parallel for schedule(static), default(none), shared(SD) 

4) 함수 호출시 SD datamembers를 사용하십시오.

이 부분이 충분히 명확 해졌기를 바랍니다. 누군가가 더 우아한 해결책을 제시해 주면 고맙겠습니다.

옵션 iii)의 전용 변수를 원하면 shared(SD) 대신 firstprivate(SD)을 사용할 수 있습니다. 이렇게하면 각 스레드가 원래 값으로 초기화되어 SD의 개인 복사본이 만들어집니다. 직렬 액세스를 피함으로써 성능상의 이점을 줄 수도 있고하지 않을 수도 있습니다. 나는 며칠 전 비슷한 문제가 있었지만 아무런 차이가 없었다.

-2

당신은 당신이 한거나 중요한 부분이기 때문에 간단하게 병렬화하지 않는 문 경우 확인하거나 보장해야하는 경우는, 스레드가 실행되는 순서를 보장 할 수 없습니다.

http://bisqwit.iki.fi/story/howto/openmp/

+0

단순히 병렬 처리하지 마십시오? 정말? 이것은 받아 들일 수있는 대답이 아닙니다. – Gilad

관련 문제