C++矩阵计算效率

Sun*_*ner 5 c++ algorithm performance matrix eigen

我们正在尝试优化我们的C++代码,并且我们有以下矩阵计算(使用Eigen库)

#include<Eigen/Dense>

int main(){

   MatrixXd P = MatrixXd::Random(30,30); // a  random double 30 x 30 matrix P
   MatrixXd M = MatrixXd::Random(30,30); // a  random double 30 x 30 matrix M
   Matrix<double, 30, 30> I; 
   I.setIdentity(); // I is an 30 x 30 identity matirx

   P = (I-M)*P

   return 0;

   }
Run Code Online (Sandbox Code Playgroud)

它们都是nxn矩阵,而我是单位矩阵.我们发现重写了上面的矩阵计算

   P= (I- M)*P
Run Code Online (Sandbox Code Playgroud)

   P = P-M*P
Run Code Online (Sandbox Code Playgroud)

使用gcc 6.2编译器在Linux ubuntu系统中加速~4-8倍.我意识到这样一个事实:编译器可能对身份矩阵和事实I*P = P一无所知,但仍无法解决使效率提高如此之多的问题.有谁知道可能的原因做出如此重大的改进?

cht*_*htz 1

首先,I.identity();不存在。你想要的是I.setIdentity(),或者P = (MatrixXd::Identity(30,30)-M)*PI如果您使用第一个选项,Eigen 肯定需要对and进行完整的 30x30 减法M(编译器很难看到与第二个表达式的等价性)。总的来说,这将产生两个临时值(一个用于差异,一个用于产品)。

如果您实际上使用了I.Identity()您正在调用的静态函数,例如成员函数,并且您的编译器至少应该警告您这一点。这实际上不会修改I,并且您最终会在 中得到未初始化的值I,其中可能会包含一些 NaN 或非正规值,这两者都可能对浮点性能不利。当然你的结果是错误的。

总的来说,我认为写方程最简单的方法是

P -= M*P;
Run Code Online (Sandbox Code Playgroud)

或者

MatrixXd Pnew = P - M*P;
Run Code Online (Sandbox Code Playgroud)