用于快速求解线性系统的C ++ Eigen

时间:2018-11-11 08:38:00

标签: c++ visual-studio matlab benchmarking eigen

所以我想测试C ++ vs Matlab求解线性方程组的速度。为此,我创建了一个随机系统,并使用Visual Studio上的Eigen测量解决该问题所需的时间:

#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 ++更快。

  • 我正在配置管理器上启用释放模式的情况下运行它
  • 项目属性-C / C ++-优化-/ O2已激活
  • 尝试使用增强指令(SSE和SSE2)。 SSE实际上使它变慢了,而SSE2几乎没有任何改变。
  • 我正在使用Visual Studio的社区版本,如果有什么不同

1 个答案:

答案 0 :(得分:4)

首先,对于这种操作,Eigen不太可能击败MatLab,因为后者会直接调用经过高度优化和多线程的英特尔MKL。请注意,您还可以将Eigen配置为回退到MKL,请参见how。如果这样做,最终将获得相似的性能。

尽管如此,6.4s是很多方法。本征documentation报告将4k x 4k矩阵分解为0.7s。在我的计算机(Haswell膝上型计算机@ 2.6GHz)上运行示例时,我得到了1.6s(clang 7,-O3 -march = native),并且启用了多线程(-fopenmp)为1s。因此,请确保启用所有CPU功能(AVX,FMA)和openmp。使用OpenMP,您可能需要将Openmp线程数显着减少为物理核心数。