0

我正在转换我自己的一些向量代数代码以使用优化的 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>

我自己的实现是一个简单的嵌套循环迭代,其中矩阵只是一个二维双数组:

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 倍?我没有正确写乘法吗?还是有另一个图书馆更适合这个?

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

4

3 回答 3

2

uBlas 在设计时并未将性能作为第一目标。有些库比 uBlas 快得多。参见例如http://eigen.tuxfamily.org/index.php?title=Benchmark

于 2011-06-13T14:33:58.153 回答
1

这个 pdf对各种线性代数库进行了相当详细的比较。我在Computational Science Stack Exchange的这个答案中遇到了这个问题,这可能是解决这类问题的更好地方。

于 2012-03-22T11:21:37.550 回答
0

不确定这是否是减速的原因(您是否配置文件以获得您的 4x 号码?)但这个循环可能很慢:

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

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

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

大多数编译器应该看到这是复制双精度并进行最佳复制,这可能会在一定程度上解决您的问题。

于 2011-06-13T14:16:19.220 回答