2011-05-01 5 views
2

벡터에 행렬을 곱하는 프로그램을 작성했습니다. 행렬에는 주기적으로 반복되는 셀이 있으므로 곱하기 전에 벡터 요소를 더하기 위해 임시 변수를 사용합니다. 기간은 인접한 행에 대해 동일합니다. 각 스레드에 대해 별도의 임시 변수를 만듭니다. sizeof (InnerVector) == 400이고 매 반복 (= 600 회)마다 메모리를 할당하고 싶지 않습니다.OpenMP에서 잘못된 결과 얻기

코드는 다음과 같은 :

tempsSize = omp_get_max_threads(); 
InnerVector temps = new InnerVector[tempsSize]; 

for(int k = 0; k < tempsSize; k++) 
    InnerVector_init(temps[k]); 

for(int jmin = 1, jmax = 2; jmax < matrixSize/2; jmin *= 2, jmax *= 2) 
{ 
    int period = getPeriod(jmax); 

    #pragma omp parallel 
    { 
     int threadNum = omp_get_thread_num(); 
     // printf("\n threadNum = %i", threadNum); 

     #pragma omp for 
     for(int j = jmin; j < jmax; j++) 
     { 
      InnerVector_reset(temps[threadNum]); 
      for(int i = jmin; i < jmax; i++) 
      { 
       InnerMatrix cell = getCell(i, j); 
       if(temps[threadNum].IsZero) 
        for(int k = j; k < matrixSize; k += period) 
         InnerVector_add(temps[threadNum], temps[threadNum], v[k]); 
       InnerVector_add_mul(v_res[i], cell, temps[threadNum]); 
      } 
     } 
    } 
} 

코드는 올바른 것으로 보이지만, 내가 잘못 결과를 얻을. 사실, 다른 실행에 대해 다른 결과를 얻습니다 ... 때로는 결과가 정확합니다.

디버그 모드로 컴파일하면 결과가 항상 올바르다. "printf"로 행의 주석 처리를 제거하면 결과가 항상 정확합니다.

p.s. 나는 병렬화 된 루프의 각 반복에 jmax에 비주얼 스튜디오를 jmin에서 2010 년

+1

무엇이 v []입니까? 스레드로부터 안전합니까? –

+0

InnerVector * v; // 곱하기 위해 필요한 "InnerVector"타입의 배열. – Shamil

답변

3
나는 결과 벡터로 나타납니다
InnerVector_add_mul(v_res[i], cell, temps[threadNum]);

v_res 이후에 데이터 경주가 없다고 생각

i 변경 사용 복수 스레드가 i의 동일한 값에 대해 v_res[i]에 쓰고 예기치 않은 결과가 발생할 수 있습니다.

+0

네, 맞습니다. 고맙습니다. – Shamil

+0

올바른지 확인하려면 "for j"와 "for i"를 전환해야합니다. 하지만이 방법은 "temp one time for several i"최적화를 잃어 버릴 것입니다 ... – Shamil

+0

@Shamil :이 대답이 맞으면 투표 카운터 아래의 체크 표시를 클릭하여 동의하십시오. – Jacob