所以我想测试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 ++更快。
答案 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线程数显着减少为物理核心数。