本征 LDLT 比 LLT 慢?

Cal*_*ior 3 c++ eigen

我正在使用 Eigen 3 的 Cholesky 模块来求解线性方程组。Eigen 文档指出,为此目的使用LDLT而不是LLT会更快,但我的基准测试显示了不同的结果。

我使用以下代码进行基准测试:

#include <iostream>
#include <chrono>
#include <Eigen/Core>
#include <Eigen/Cholesky>
using namespace std;
using namespace std::chrono;
using namespace Eigen;

int main()
{
    MatrixXf cov = MatrixXf::Random(4200, 4200);
    cov = (cov + cov.transpose()) + 1000 * MatrixXf::Identity(4200, 4200);
    VectorXf b = VectorXf::Random(4200), r1, r2;

    r1 = b;
    LLT<MatrixXf> llt;
    auto start = high_resolution_clock::now();
    llt.compute(cov);
    if (llt.info() != Success)
    {
        cout << "Error on LLT!" << endl;
        return 1;
    }
    auto middle = high_resolution_clock::now();
    llt.solveInPlace(r1);
    auto stop = high_resolution_clock::now();
    cout << "LLT decomposition & solving in  " << duration_cast<milliseconds>(middle - start).count()
         << " + " << duration_cast<milliseconds>(stop - middle).count() << " ms." << endl;

    r2 = b;
    LDLT<MatrixXf> ldlt;
    start = high_resolution_clock::now();
    ldlt.compute(cov);
    if (ldlt.info() != Success)
    {
        cout << "Error on LDLT!" << endl;
        return 1;
    }
    middle = high_resolution_clock::now();
    ldlt.solveInPlace(r2);
    stop = high_resolution_clock::now();
    cout << "LDLT decomposition & solving in " << duration_cast<milliseconds>(stop - start).count()
         << " + " << duration_cast<milliseconds>(stop - middle).count() << " ms." << endl;

    cout << "Total result difference: " << (r2 - r1).cwiseAbs().sum() << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经g++ -std=c++11 -O2 -o llt.exe llt.cc在 Windows 上编译了它,这就是我得到的:

LLT decomposition & solving in  6515 + 15 ms.
LDLT decomposition & solving in 8562 + 15 ms.
Total result difference: 1.27354e-006
Run Code Online (Sandbox Code Playgroud)

那么,为什么 LDLT 比 LLT 慢?我做错了什么还是我误解了文档?

gga*_*ael 6

文档中的这句话已经过时了。使用 Eigen 的最新版本,LLT 对于相当大的矩阵应该比 LDLT 快得多,因为 LLT 实现利用了缓存友好的矩阵-矩阵操作,而 LDLT 实现仅涉及旋转和矩阵-向量操作。随着开发分支你的例子给了我:

LLT decomposition & solving in  380 + 4 ms.
LDLT decomposition & solving in 2746 + 4 ms.
Run Code Online (Sandbox Code Playgroud)