uBLAS Slow Matrix-SparseVector乘法

时间:2011-06-13 13:17:38

标签: c++ boost linear-algebra blas ublas

我正在转换我自己的一些矢量代数代码,以使用优化的boost uBLAS库。但是,当我尝试进行SymmetricMatrix-SparseVector乘法时,我发现它比我自己的实现慢大约4倍。矢量大小通常在0-500左右,大约70-80%的条目为零。

这是我的代码

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

}

为什么uBLAS 4x更慢?我没有正确地写出乘法吗?还是有另一个更适合这个的图书馆吗?

编辑:如果我使用密集的矢量数组,那么uBLAS只会慢2倍......

3 个答案:

答案 0 :(得分:2)

uBlas的设计并没有考虑到第一个目标。有些库比uBlas快得多。参见例如http://eigen.tuxfamily.org/index.php?title=Benchmark

答案 1 :(得分:1)

This pdf对各种线性代数库进行了非常详细的比较。我在this answer Computational Science Stack Exchange发现了这个问题,对于这类问题来说,这可能是一个更好的地方。

答案 2 :(得分:0)

不确定是否是导致减速的原因(你是否得到了你的4x号码?)但是这个循环可能很慢:

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

如果大部分时间花在处理代码中的循环上,那么这个额外的循环可能会使时间翻倍(并且与ublas无关)。我建议改为使用std::copy

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

大多数编译器应该看到这是复制double并执行最佳复制,这可能会在某种程度上解决您的问题。