2011-06-13 43 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