我想使用 C++ 进行大型线性代数计算。首先,我用 C++ 和 matlab 创建了这些比较程序。我也在这里给出了惊人的执行时间。您能否建议击败 matlab 或至少获得可比性能的方法?我知道 C++ 使用高度矢量化的方法进行计算。那么在涉及线性代数的大型科学编程中,是否应该始终使用 matlab 而不是 C++?我个人认为 matlab 不能为大型计算提供良好的性能,因此在这种情况下,C++ 比 matlab 更受欢迎。然而,我的计划结果与这种信念相反。
用 gcc 编译的 C++ 程序:
#include <iostream>
#include <Eigen\Dense> //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;
}
Run Code Online (Sandbox Code Playgroud)
执行时间:24.141 秒
这是matlab程序:
function [ ] = Trial( )
clear all;
close all;
clc;
tic;
A=rand([1000,1000]);
B=rand([1000,1000]);
C=A*B;
toc
end
Run Code Online (Sandbox Code Playgroud)
经过的时间是 0.073883 秒。
MATLAB
即使打开了所有优化,它也很难被击败。要充分利用Eigen
您需要使用并行支持 ( -fopenmp
in gcc
)进行编译,并打开优化 ( -O3
)。即使在这种情况下,MATLAB
也会稍微快一点,主要是因为它使用英特尔 MKL 专有库来充分利用英特尔芯片,所以除非您购买它,否则我认为您无法击败它。我目前正在Eigen
用于一个项目并且无法击败MATLAB
(至少不是用于密集矩阵乘法)。
例如,对于A*B
whereA
和B
are1000 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
Run Code Online (Sandbox Code Playgroud)
为了充分利用 Eigen,编译时启用优化(例如 -O3 编译器标志),启用 OpenMP(例如 -fopenmp),并禁用超线程或指定 openmp 的真实物理内核数(例如,export OMP_NUM_THREADS= 4 如果您有 8 个超线程“核心”,但有 4 个物理核心)。
最后,如果您的 CPU 支持 FMA(例如,-mfma),您还可以考虑使用 devel 分支并启用 AVX(例如,-mavx)和 FMA。