如何在matlab环境下用特征库加速这个c++程序

How to speed up this C++ program with eigen library against matlab?

本文关键字:加速 程序 c++ 特征 matlab 环境      更新时间:2023-10-16

我想使用c++进行大型线性代数计算。作为第一步,我用c++和matlab编写了这些比较程序。我也给出了惊人的执行时间。你能建议如何击败matlab或至少获得相当的性能吗?我知道c++使用高度矢量化的方法进行计算。那么在涉及线性代数的大型科学编程中,应该总是使用matlab而不是c++吗?我个人认为matlab对于大型计算的性能不是很好,所以在这种情况下c++比matlab更受欢迎。然而,我的程序结果却与此相反。

用gcc编译的c++程序:

#include <iostream>
#include <EigenDense> //EIGEN library
using namespace Eigen;
using namespace std;
int main()
{
MatrixXd A;
A.setRandom(1000, 1000);
MatrixXd B;
B.setRandom(1000, 1000);
MatrixXd C;
C=A*B;
}

执行时间:24.141 s

下面是matlab程序:
function [  ] = Trial(  )
clear all;
close all;
clc;
tic;
A=rand([1000,1000]);
B=rand([1000,1000]);
C=A*B;
toc
end

运行时间为0.073883秒。

即使打开了所有优化,也很难击败MATLAB。为了充分利用Eigen,您需要使用并行支持(gcc中的-fopenmp)进行编译,并打开优化(-O3)。即使在这种情况下,MATLAB也会稍微快一点,主要是因为它使用英特尔MKL专有库来最大限度地利用英特尔芯片,所以除非你买它,否则我认为你无法击败它。我目前在一个项目中使用Eigen,并且无法击败MATLAB(至少不能用于密集矩阵乘法)。

例如,对于A*B,其中AB1000 x 1000复矩阵,我可以得到的最佳平均时间为:

MATLAB: 0.32秒Eigen: 0.44秒

对于2000 x 2000

MATLAB: 2.80秒Eigen: 3.45秒

操作系统:MacbookPro 2013, OS x

PS:你应该绝对确保你打开了优化(-O3),也编译并行支持,-fopenmp。这就是为什么你可能会在运行时间上得到如此巨大的差异。因此,您应该将程序编译为:

g++ -O3 -fopenmp <other compiling flags/parameters> main.cpp

为了获得最好的Eigen,编译时启用优化(例如-O3编译器标志),启用OpenMP(例如-fopenmp),并禁用超线程或指定OpenMP物理内核的真实数量(例如,如果您有8个超线程"内核",则导出OMP_NUM_THREADS=4)。

最后,如果你的CPU不支持FMA(例如-mfma),你也可以考虑使用devel分支并启用AVX(例如-mavx)和FMA。

实际上Matlab(如果您不购买昂贵的并行计算工具箱)几乎不使用多线程。它只在Matlab调用的库中使用,这些库可能比你现在使用的更有效。

您可以查看此链接以了解(并检查)Matlab使用的库http://undocumentedmatlab.com/blog/math-libraries-version-info-upgrade

也可以在C程序中使用它们(尽管它们可能隐藏了头文件或其他东西,但至少您仍然拥有.dll,因为它们需要运行Matlab)