我们正在尝试优化我们的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;
}
它们都是nxn矩阵,而我是单位矩阵。 我们发现重写了上面的矩阵计算
P= (I- M)*P
作为
P = P-M*P
使用gcc 6.2编译器在Linux ubuntu系统中加速~4-8倍。我意识到这样一个事实:编译器可能对身份矩阵和事实I * P = P一无所知,但仍无法解决使效率提高如此之多的问题。有谁知道可能的原因做出如此重大的改进?
答案 0 :(得分:1)
首先,I.identity();
不存在。您想要的是I.setIdentity()
或P = (MatrixXd::Identity(30,30)-M)*P
。
如果你使用第一个选项,Eigen肯定需要完成I
和M
的完整30x30减法(编译器很难看到与第二个表达式的等价)。总的来说,这将产生两个临时值(一个用于差异,一个用于产品)。
如果您实际使用I.Identity()
,则调用静态函数(如成员函数),并且您的编译器至少应该警告您。这实际上不会修改I
,并且您最终会在I
中找到未初始化的值,这可能包含一些NaN或非正规值,这两者都可能对浮点性能不利。当然,你的结果是错误的。
总的来说,我认为编写等式的最简单方法是
P -= M*P;
或
MatrixXd Pnew = P - M*P;