简体   繁体   中英

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

I am new to c++ and the Eigen library. I want to perform LU decomposition (partial pivoting) on a matrix of size 1815 X 1815 , with complex entries. However, the performance of my code is bad, the LU decomposition is taking 77.2852 seconds, compared to MATLAB taking only 0.140946 seconds. Please find the attached code. Any advice on how I can improve the code? Please note that in the first part of the code, I am importing the matrix from a file with entries: a + bi , where a and b are complex numbers. The matrix file was generated from MATLAB. Thank you.

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

} 


I'll summarize the comments into an answer.

When you feel that Eigen is running slow there are a list of things that should be verified.

  1. Are optimizations turned on?
    Eigen is a template heavy library that does a lot of compile time checks and that should be optimized out. If optimizations are not on, none of it gets inlined and many pointless function calls are made. Turning on even the lowest level of optimizations usually alleviates most of this ( -O1 or higher in gcc/clang, /O1 or higher in MSVC). General notes on optimizations can be found here .
  2. Am I utilizing all the hardware options?
    A lot of code in Eigen can be vectorized if allowed. Make sure that this is enabled with flags turning on SSE/AVX/etc. if the target hardware supports it. Enable FMA if available as well. There's a placeholder doc here .
  3. Enable multithreading
    If your process/hardware allow, consider enabling OpenMP to allow Eigen to utilize multiple cores for some of the operations.
  4. Use the right precision
    In many applications, only the first few digits matter. If this is the case in your application, consider using single precision instead of double precision.
  5. Link to a fine tuned library
    In the end, Eigen spits out some finely built C++ code and relies on the compiler to handle most of the optimizations itself. In some cases, a more finely tuned library such as MKL may improve performance. Eigen can link to MKL to squeeze a bit more speed out of the hardware.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM