C ++ Eigen для быстрого решения линейных систем - PullRequest
0 голосов
/ 11 ноября 2018

Итак, я хотел проверить скорость C ++ против Matlab для решения линейной системы уравнений. Для этого я создаю случайную систему и измеряю время, необходимое для ее решения, используя Eigen в Visual Studio:

#include <Eigen/Core>
#include <Eigen/Dense>
#include <chrono>

using namespace Eigen;
using namespace std;

int main()
{
    chrono::steady_clock sc;   // create an object of `steady_clock` class
    int n;
    n = 5000;
    MatrixXf m = MatrixXf::Random(n, n);
    VectorXf b = VectorXf::Random(n);
    auto start = sc.now();     // start timer
    VectorXf x = m.lu().solve(b);
    auto end = sc.now();
    // measure time span between start & end
    auto time_span = static_cast<chrono::duration<double>>(end - start);
    cout << "Operation took: " << time_span.count() << " seconds !!!";
}

Решение этой системы 5000 x 5000 занимает в среднем 6,4 секунды. То же самое в Matlab занимает 0,9 секунды. Код Matlab выглядит следующим образом:

a = rand(5000);  b = rand(5000,1);

tic
x = a\b;
toc

Согласно этой блок-схеме оператора обратной косой черты:

учитывая, что случайная матрица не является треугольной, переставленной треугольной, эрмитовой или верхней Гейзенберга, оператор обратной косой черты в Matlab использует решатель LU, который, как я считаю, тот же, что и используемый в коде C ++, то есть lu().solve

Возможно, что-то мне не хватает, потому что я думал, что C ++ был быстрее.

  • Я запускаю его с активным режимом выпуска в Configuration Manager
  • Свойства проекта - C / C ++ - Оптимизация - / O2 активен
  • Пробовал с использованием расширенных инструкций (SSE и SSE2). SSE фактически сделал это медленнее, а SSE2 почти ничего не изменило.
  • Я использую версию Visual Studio для сообщества, если это имеет какое-либо значение

1 Ответ

0 голосов
/ 11 ноября 2018

Прежде всего, для такого рода операций Eigen вряд ли превзойдет MatLab, потому что позже он будет напрямую называть MKL от Intel, который сильно оптимизирован и многопоточен. Обратите внимание, что вы также можете настроить Eigen для возврата к MKL, см. how . Если вы сделаете это, вы получите аналогичную производительность.

Тем не менее, 6.4s - это путь к многим. Документация Eigen сообщает 0,7 с для факторизации матрицы 4k x 4k. Запустив ваш пример на моем компьютере (ноутбук Haswell @ 2,6 ГГц), я получил 1,6 с (clang 7, -O3 -march = native) и 1 с включенной многопоточностью (-fopenmp). Поэтому убедитесь, что вы включили все функции вашего процессора (AVX, FMA) и openmp. С OpenMP вам может понадобиться явно сократить количество потоков openmp до количества физических ядер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...