2011-06-13 51 views
0

我正在轉換一些我自己的矢量代數代碼,以使用優化的boost uBLAS庫。但是,當我嘗試執行SymmetricMatrix-SparseVector乘法時,發現它比我自己的實現慢大約4倍。矢量大小通常在0-500左右,大約70-80%的條目爲零。uBLAS慢矩陣 - SparseVector乘法

這是我的代碼

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); 
    } 
} 

sparseVectorIndexes存儲輸入矢量的非零值的索引,vectorLength是矢量的長度,和sparseLength是非零的載體中的數。該矩陣被存儲爲對稱矩陣symmetric_matrix<double, lower>

我自己的實現是一個簡單的嵌套循環迭代,其中矩陣只是一個2D雙陣列:

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; 
    } 

}

爲什麼是4倍的uBLAS庫慢?我不是在正確地寫乘法嗎?還是有另一個圖書館更適合這個?

編輯:如果我使用一個密集的矢量陣列,而不是那麼的uBLAS只有2倍慢...

+0

如果這是在Visual Studio中,你是否檢查你是否在調試模式下編譯它? – Jacob 2011-06-13 13:34:21

+0

絕對編譯爲Release,優化全部,並且不在IDE中測試。 – 2011-06-13 13:40:47

+0

請張貼擴展代碼 - vectorIn'從哪裏來,它的類型是什麼?在第二個非uBlas代碼中創建了哪些對象副本?請張貼您正在測量的所有代碼,以獲得4倍速度減慢數字。 – 2011-06-13 13:47:57

回答

2

uBlas的設計並沒有考慮到目標1的性能。有些庫比uBlas快得多。見例如http://eigen.tuxfamily.org/index.php?title=Benchmark

+0

哇。這可能是原因。我的印象是uBLAS是最快的,不知道我從哪裏挑選。稍後再試試。 – 2011-06-13 14:46:43

+3

@Projectile:Boost.uBLAS可以作爲LAPACK,UMFPACK,MUMPS等的一個單純的前端,在不改變任何代碼的情況下將其性能提高數量級。請參閱[本頁](http://mathema.tician.de/node/391)瞭解更多信息。 – ildjarn 2011-06-13 16:57:39

0

不知道這是經濟放緩的原因(?你個人資料,讓您的4倍數字)但是這個循環可能是緩慢:

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

如果大部分的時間都花在處理你的代碼,然後這些額外的循環可能會增加一倍的時間(並沒有什麼用的uBLAS做)的循環。我會建議使用std::copy代替:

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

大多數編譯器應該看到,這是複製雙,做一個最佳的副本,這可能有點解決您的問題。

+0

謝謝,但我很確定它的實際刺激倍增速度很慢。如果我只是從代碼中刪除最後一個循環,那麼性能幾乎沒有區別。我做了配置文件來獲得這個4倍數字。 – 2011-06-13 14:19:23