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一无所知,但仍无法解决使效率提高如此之多的问题.有谁知道可能的原因做出如此重大的改进?
首先,I.identity();不存在。你想要的是I.setIdentity(),或者P = (MatrixXd::Identity(30,30)-M)*P。I如果您使用第一个选项,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)