2011-10-17 3 views
4

부스트 ublas 제품 성능을 향상시킬 수있는 방법이 있습니까?부스트 uBLAS 매트릭스 제품이 매우 느림

나는 두 행렬 A, 내가 추가/mulitply 할 B를/부/...이 C 대 MATLAB에서

++ 내가 얻을 2000x2000 매트릭스 운영

OPERATION | MATLAB | C++ (MSVC10) 
A + B  | 0.04 | 0.04 
A - B  | 0.04 | 0.04 
AB  | 1.0 | 62.66 
A'B'  | 1.0 | 54.35 
에 대해 다음 번 [S]

여기 왜 이렇게 큰 성능 손실이 있습니까?

매트릭스는 실제 2 배입니다. 그러나 나는 또한 긍정적 인 한정, 대칭, 사각형 제품이 필요합니다.

EDIT : 코드는 사소한

matrix<double> A(2000 , 2000); 
// Fill Matrix A 
matrix<double> B = A; 

C = A + B; 
D = A - B; 
E = prod(A,B); 
F = prod(trans(A),trans(B)); 

EDIT 2 결과 할려고 10의 평균 값이다. (!) : 모든이 릴리스에서 퇴장했다 (NDEBUG/MOVE_SEMANTICS/..) 모드 STDDEV는 내가 요인 2-3 어쩌면에 있지만 50

EDIT 3 기대 이하 0.005

했다.

EDIT 4 : 제품 결과에 사전 할당 된 행렬은 런타임에 영향을 미치지 않습니다.

+0

깨끗한 Matlab 재실행을 꼭해야합니다. 캐시하는 경향이 있습니다. 음, 모든 것. 완전히 관련이 없지만 괜찮은 성능과 [Eigen] (http://eigen.tuxfamily.org/index.php?title=Main_Page)의 쉬운 구문을 얻을 수 있어야합니다. (나는 당신의 작은 벤치 마크, 힌트 힌트와 관련이있는 방법에 관심이있다 :-) – rubenvb

+2

나는 곱셈 vs 추가에 ~ 2000x 시간을 기대한다. – ruslik

+2

uBlas의 해제 모드를 켜는 것을 잊지 않았다. [link = http : //www.boost.org/doc/libs/1_47_0/libs/numeric/ublas/doc/index.htm] 끝에있는 [http://www.boost.org/doc/index.htm] 끝에있는 FAQ를 참조하십시오. '-DNDEBUG'또는 일부 다른 플래그를 사용하여 ublas를 릴리스 용으로 컴파일합니다. –

답변

4

가능한 모든 최적화에 대한 조언을 위해 C + 코드를 게시하십시오.

그러나 Matlab은 설계된 작업에 대해 매우 전문화되어 있으므로 Boost를 사용하여 Matlab과 일치시킬 수는 없습니다. 반면에 Boost는 무료이지만 Matlab은 그렇지 않습니다.

필자는 uBlas 코드를 기본 LAPACK 구현에 바인딩함으로써 최상의 부스트 성능을 얻을 수 있다고 믿습니다.

+4

+1 "* 나는 최고의 부스트 성능은 uBlas 코드를 기본 LAPACK 구현에 바인딩함으로써 얻을 수 있다고 생각합니다. *"이것은 진정한 해답입니다. – ildjarn

0

여기서 메모리 관리가 어떤 역할을하는지 알지 못합니다. prod은 32MB의 매트릭스를 할당해야하며, trans도 두 번 할당하면 10 번 모두 수행됩니다. stackhots 몇 개를 가져와 이 실제로 일을 확인하십시오. 내 바보 같은 추측은 당신이 더 나은 결과를 얻을 수있는 매트릭스를 사전에 할당하는 것입니다. 행렬 곱셈이 가속화 될 수

다른 방법이

  • 사전 전치 왼쪽 행렬을하고, 캐시 친화적 인, 그리고

  • 는 0을 스킵합니다. A (i, k)와 B (k, j)가 모두 0이 아닌 경우에만 기여한 값입니다.

이것이 uBlas에서 수행되었는지 여부는 누구나 추측 할 수 있습니다.

+0

나는 이것을 피하기 위해 표현 클래스를 사용하는 것이 좋습니다. (또는 적어도 그렇게해야합니다.) – user786653

1

ATLAS, gotoBLAS, MKL과 같이 효율적인 BLAS 구현이 많이 있지만 대신 사용할 수 있습니다.

코드에서 선택하지는 않지만, ubas :: prod (A, B)는 3- 루프, 블록 및 친숙하지 않은 캐시를 사용합니다. 그것이 사실이라면, prod (A, B.trans())는 다른 것보다 훨씬 빠를 것입니다.

cblas를 사용할 수있는 경우 cblas_dgemm을 사용하여 계산을 수행하십시오. 그렇지 않다면 단순히 데이터, 즉 prod (A, B.trans())를 재정렬 할 수 있습니다.

2

불필요한 사본을 제거하려면 행렬 곱셈의 왼쪽에 noalias을 사용해야합니다.

왼쪽 손 표현과 오른쪽 표현이 공통 저장이 없다는 것을 확실히 알고있는 경우는, 다음 과제는 더 앨리어싱이없는 대신 E = prod(A,B); 사용 설명서에서 noalias(E) = prod(A,b);

. 이 경우보다 효율적인 할당을 지정할 수 있습니다. noalias (C) = prod (A, B); 이렇게하면 일반 할당에서 이 필요한 임시 매트릭스가 작성되지 않습니다. 'noalias'과제는 왼쪽과 오른쪽이 크기에 맞도록 을 요구합니다.