2013-03-17 5 views
0

편집 : 내 첫 번째 코드 샘플이 잘못되었습니다. 고정되어 있습니다.OpenMP 및 메모리 대역폭 제한

대용량 벡터와 행렬 간의 대수 연산을위한 C++ 라이브러리를 구현합니다. x86-x64 CPU에서 OpenMP 병렬 벡터 추가, 내 제품 등이 단일 스레드보다 빠르다고 느꼈습니다. 병렬 작업은 단일 스레드보다 -1 % ~ 6 % 빠릅니다. 이것은 메모리 대역폭 제한 때문에 발생합니다 (필자 생각). 이 샘플에서

void DenseMatrix::identity() 
{ 
    assert(height == width); 
    size_t i = 0; 
    #pragma omp parallel for if (height > OPENMP_BREAK2) 
    for(unsigned int y = 0; y < height; y++) 
     for(unsigned int x = 0; x < width; x++, i++) 
      elements[i] = x == y ? 1 : 0; 
} 

의 OpenMP를 사용에서 심각한 결점이없는 :

그래서, 질문은, 거기에 이런 코드에 대한 실시간 성능 혜택입니다. 그러나 스파 스 벡터 및 스파 스 매트릭스가있는 OpenMP로 작업하는 경우 인스턴스 * .push_back()을 사용할 수 없으며이 경우 질문이 심각 해집니다. (스파 스 벡터 벡터의 요소는 고밀도 벡터와 같이 연속적이지 않으므로 결과 요소는 언제든지 도착할 수 있기 때문에 단점이 있습니다 (낮은 색인에서 높은 인덱스가 아님)

답변

1

나는 이것이 메모리 대역폭의 문제라고 생각하지 않습니다. r에 대한 명확한 문제가 있음을 알 수 있습니다. 데이터 레이스가이 모두 인 false가되는 여러 스레드에서 r에 액세스했습니다. 거짓 공유는 귀하의 실적을 크게 해칠 수 있습니다.

데이터 레이스가 r에 있기 때문에 올바른 답을 얻을 수 있는지 궁금합니다. 정답을 얻었습니까?

그러나 솔루션은 매우 간단합니다. r에서 수행 된 작업은 감소입니다. 이는 OpenMP에서 쉽게 수행 할 수 있습니다.

시도

단순히 #pragma omp parallelreduction(+ : r)을 추가합니다.

(참고 :.. double에 추가 시리얼 코드의 결과에 약간의 차이 당신은 몇 가지 정밀 오류가 발생할 수 있습니다 교환 법칙과 결합하지 않거나)