2011-06-13 2 views
0

최적화 된 부스트 uBLAS 라이브러리를 사용하기 위해 자신의 벡터 대수 코드를 변환 중입니다. 그러나 SymmetricMatrix-SparseVector 곱셈을 할려고 할 때, 내 구현보다 약 4 배 느린 것으로 나타났습니다. 벡터 크기는 일반적으로 약 0-500이며 약 70-80 % 항목은 0입니다. 여기 uBLAS 저조한 매트릭스 - SparseVector 곱셈

내 코드

sparseVectorIndexes 입력 벡터의 비 - 제로 값의 인덱스를 저장

void CRoutines::GetA(double a[], double vectorIn[], int sparseVectorIndexes[], int vectorLength, int sparseLength) 
{ 
    compressed_vector<double> inVec (vectorLength, sparseLength); 
    for(int i = 0; i < sparseLength; i++) 
    { 
     inVec(sparseVectorIndexes[i]) = vectorIn[sparseVectorIndexes[i]]; 
    } 
    vector<double> test = prod(inVec, matrix); 
     for(int i = 0; i < vectorLength; i++) 
    { 
     a[i] = test(i); 
    } 
} 
이다 vectorLength는 벡터의 길이이고, sparseLength는 벡터 내의 비 제로의 개수 . 행렬은 대칭 행렬 symmetric_matrix<double, lower>으로 저장됩니다.

void CRoutines::GetA(double a[], double vectorIn[], int sparseVectorIndexes[], int vectorLength, int sparseLength) 
{ 
    for (int i = 0; i < vectorLength; i++) 
    { 
      double temp = 0; 

      for (int j = 0; j < sparseLength; j++) 
      { 
       int row = sparseVectorIndexes[j]; 
       if (row <= i) // Handle lower triangular sparseness 
        temp += matrix[i][row] * vectorIn[row]; 
       else 
        temp += matrix[row][i] * vectorIn[row]; 
      } 
      a[i] = temp; 
    } 

}

가 왜 느린 uBLAS 4 배입니다 :

내 자신의 구현은 매트릭스 그냥 2D double 배열하는 간단한 중첩 된 루프 반복인가? 곱셈을 올바르게 쓰지 않습니까? 아니면 이것에 더 적합한 또 다른 도서관이 있습니까?

편집 : 조밀 한 벡터 배열을 사용하는 경우가 침체의 원인 인 경우 대신 다음 uBLAS이 ... 확실하지

+0

Visual Studio에서 디버그 모드로 컴파일 중인지 확인 했습니까? – Jacob

+0

Release로 컴파일하고, IDE에서 테스트를하지 않고 모두 최적화합니다. –

+0

확장 코드를 게시하십시오 - 'vectorIn'은 어디에서 왔으며, 그 타입은 무엇입니까? 두 번째 비 uBlas 코드에서 생성되는 객체 복사본은 무엇입니까? 측정 코드가 4x 속도 저하 번호를 표시하도록 게시하십시오. –

답변

2

uBlas는 목표 1을 염두에두고 설계되지 않았습니다. uBlas보다 훨씬 빠른 라이브러리가 있습니다. 예 : http://eigen.tuxfamily.org/index.php?title=Benchmark

+0

와우. 이것이 이유가 될 수 있습니다.나는 uBLAS가 가장 빠르다는 인상을 받고있었습니다. 나중에 eigen a try 시도합니다. –

+3

@Projectile : Boost.uBLAS는 LAPACK, UMFPACK, MUMPS 등의 프론트 엔드 역할을 할 수 있으며 코드를 변경하지 않고도 성능을 엄청나게 향상시킬 수 있습니다. 자세한 정보는 [이 페이지] (http://mathema.tician.de/node/391)를 참조하십시오. – ildjarn

0

배속 느린 (? 당신이 당신의 배 번호를 얻기 위해 프로파일 않았다) 그러나이 루프는 느릴 수 :

for(int i = 0; i < vectorLength; i++) 
    { 
     a[i] = test(i); 
    } 

대부분의 시간은 다음이 추가 루프 시간을 두 배 (그리고 ublas와는 아무 상관이 없다) 수있는 코드에서 루프를 처리하는 데 소요됩니다. 내가 대신 std::copy를 사용하는 것이 좋습니다 :

std::copy(test.begin(), test.end(), a[0]) 

대부분의 컴파일러는이 이중 복사되는 것을보고 다소 문제를 해결할 수있는 최적의 사본을해야한다.

+0

고마워,하지만 나는 실제 곱셈이 느리다는 것을 확신한다. 코드에서 마지막 루프를 제거하면 성능에 거의 차이가 없습니다. 저는 그 4x 숫자를 얻기 위해 프로필을했습니다. –