Как ускорить разложение LU в Eigen C ++? - PullRequest
1 голос
/ 23 января 2020

Я новичок в c ++ и библиотеке Eigen. Я хочу выполнить декомпозицию LU (частичное вращение) на матрице размером 1815 X 1815 со сложными записями. Однако производительность моего кода плохая, декомпозиция LU занимает 77.2852 секунды, в то время как MATLAB занимает всего 0.140946 секунды. Пожалуйста, найдите прикрепленный код. Любой совет, как я могу улучшить код? Обратите внимание, что в первой части кода я импортирую матрицу из файла с записями: a + bi, где a и b - комплексные числа. Файл матрицы был сгенерирован из 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; 

} 


1 Ответ

1 голос
/ 29 января 2020

Я суммирую комментарии в ответ.

Когда вы чувствуете, что Eigen работает медленно, есть список вещей, которые необходимо проверить.

  1. Включены ли оптимизации?
    Eigen - библиотека шаблонов, которая выполняет много проверок времени компиляции и должна быть оптимизирована. Если оптимизация не включена, ни одна из них не становится встроенной, и выполняется много бессмысленных вызовов функций. Включение даже самого низкого уровня оптимизации обычно облегчает большую часть этого (-O1 или выше в gcc / clang, /O1 или выше в MSV C). Общие замечания по оптимизации можно найти здесь: .
  2. Использую ли я все аппаратные опции?
    Можно разрешить векторизацию большого количества кода в Eigen, если это разрешено. Убедитесь, что это включено, когда флаги включают SSE / AVX / et c. если целевое оборудование поддерживает это. Включите FMA, если доступно. Здесь есть заполнитель do c здесь .
  3. Включение многопоточности
    Если ваш процесс / оборудование позволяет, рассмотрите , включив OpenMP , чтобы разрешить Можно использовать несколько ядер для некоторых операций.
  4. Использовать правильную точность
    Во многих приложениях имеют значение только первые несколько цифр. Если дело обстоит именно так в вашем приложении, рассмотрите возможность использования одинарной точности вместо двойной точности.
  5. Ссылка на точно настроенную библиотеку
    В конце концов, Eigen выплевывает какой-то точно построенный C ++ код и полагается на компилятор для обработки большинства оптимизаций сам. В некоторых случаях более точно настроенная библиотека, такая как MKL, может улучшить производительность. Eigen может связываться с MKL , чтобы выжать немного больше скорости из аппаратного обеспечения.
...