如何加速 Eigen C++ 中的 LU 分解?

How to speed up LU decomposition in Eigen C++?

我是 c++ 和 Eigen 库的新手。我想对大小为 1815 X 1815 的矩阵执行 LU 分解(部分旋转),其中包含复杂的条目。但是,我的代码的性能很差,LU 分解需要 77.2852 秒,而 MATLAB 只需要 0.140946 秒。请找到随附的代码。关于如何改进代码的任何建议?请注意,在代码的第一部分,我从包含以下条目的文件中导入矩阵:a + bi,其中 ab 是复数。矩阵文件是从 MATLAB 生成的。谢谢。

#include <iostream>
#include <Eigen/Dense>
#include <fstream>
#include <complex>
#include <string>
#include <chrono> 

using namespace std;
using namespace std::chrono; 
using namespace Eigen;

int main(){ 

    int mat_sz = 1815; // size of matrix
    MatrixXcd c_mat(mat_sz,mat_sz); // initialize eigen matrix
    double re, im;
    char sign;
    string entry;

    ifstream myFile("A_mat"); // format of entries : a + bi. 'a' and 'b' are complex numbers

    //Import and assign matrix to an Eigen matrix

    for (int i = 0; i < mat_sz; i++){
        for (int j = 0; j < mat_sz; j++){
            myFile >> entry;

            stringstream stream(entry);
            stream >> re >> sign >> im;
            c_mat(i,j) = {re, (sign == '-') ? -im : im}; // Assigning matrix entries
        }
    }

    // LU Decomposition

    auto start = high_resolution_clock::now();

    c_mat.partialPivLu(); // Solving equation through partial LU decomposition

    auto stop = high_resolution_clock::now(); 
    auto duration = duration_cast<microseconds>(stop - start);

    double million = 1000000;

    cout << "Time taken by function: " << duration.count()/million << " seconds" << endl; 

} 


我会把评论总结成一个答案。

当您觉得 Eigen 是 运行 慢时,这里有一个清单应该验证。

  1. 优化是否开启?
    Eigen 是一个模板繁重的库,它会进行大量编译时检查,应该对其进行优化。如果未启用优化,其中 none 将被内联并进行许多无意义的函数调用。即使是最低级别的优化通常也能缓解大部分问题(-O1 或 gcc/clang 或更高级别,/O1 或更高级别的 MSVC)。关于优化的一般说明可以是 found here.
  2. 我是否利用了所有硬件选项?
    如果允许,Eigen 中的很多代码都可以向量化。确保启用标志并打开 SSE/AVX/etc。如果目标硬件支持它。如果可用,也启用 FMA。有一个占位符 doc here.
  3. 启用多线程
    如果您的 process/hardware 允许,请考虑 enabling OpenMP 以允许 Eigen 在某些操作中使用多个内核。
  4. 使用正确的精度
    在许多应用程序中,只有前几位数字很重要。如果您的应用程序属于这种情况,请考虑使用单精度而不是双精度。
  5. Link 到微调库
    最后,Eigen 吐出一些精心构建的 C++ 代码,并依靠编译器自行处理大部分优化。在某些情况下,更精细调整的库(例如 MKL)可能会提高性能。 Eigen can link to MKL 从硬件中榨取更多的速度。