【问题标题】:uBLAS Slow Matrix-SparseVector MultiplicationuBLAS 慢矩阵-稀疏向量乘法
【发布时间】:2011-06-13 13:17:37
【问题描述】:

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

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

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 倍...

【问题讨论】:

  • 如果这是在 Visual Studio 中,你是否检查过你是否在调试模式下编译它?
  • 肯定会编译到 Release,优化全部开启,而不是在 IDE 中测试。
  • 请发布扩展代码 - vectorIn 来自哪里,它的类型是什么?在第二个非 uBlas 代码中创建了哪些对象副本?请发布您正在测量的所有代码以得出 4 倍减速数字。
  • 好的,我发布了额外的代码。一些额外的信息:这段代码被编译成一个 dll 并在 C# 中调用,但我认为这根本不会有任何区别。
  • 另外,matrixtriangular_matrix&lt;double, lower&gt;?

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


【解决方案1】:

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

【讨论】:

  • 哇。这可能是原因。我的印象是 uBLAS 是最快的,不知道我是从哪里得到的。稍后会尝试 eigen。
  • @Projectile : Boost.uBLAS 可以仅作为 LAPACK、UMFPACK、MUMPS 等的前端,无需更改任何代码即可将其性能提高几个数量级。请参阅this page 了解更多信息。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

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

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

    【讨论】:

    • 谢谢,但我很确定它的实际产品乘法速度很慢。如果我只是从代码中删除最后一个循环,那么性能几乎没有差异。我做了配置文件以获得那个 4x 号码。
    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 2019-09-28
    • 2021-03-05
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    相关资源
    最近更新 更多