特征

时间:2017-03-10 07:07:09

标签: c++ performance eigen matrix-multiplication

我可以访问许多矩阵库,但是对于这个项目我使用的是Eigen,因为它的编译时间定义和它包含了SVD。

现在,我正在执行以下操作:

Eigen::Matrix<double,M,N> A;     // populated in the code

Eigen::Matrix<double,N,N> B = A.transpose() * A;

据我所知,这会制作A的副本并形成转置,再次乘以A.此操作在相对较小的矩阵(M = 20-30,N = 3)上执行,但每秒数百万次,这意味着它必须尽可能快。

我读到使用以下内容更快:

B.noalias() = A.transpose() * A;

我可以编写自己的子程序,接受A作为输入并填充B,但我想知道是否存在使用最少循环次数的高效现有实现。

1 个答案:

答案 0 :(得分:2)

首先,由于Eigen依赖于模板表达式,A.transpose()不会评估为临时表达式。

其次,在:

Matrix<double,N,N> B = A.transpose() * A;

Eigen知道B不能出现在表达式的右侧(因为这里编译器调用B的构造函数),因此根本不会创建临时值。这相当于:

Matrix<double,N,N> B;             // declare first
B.noalias() = A.transpose() * A;  // eval later

最后,对于这样的小矩阵,我不希望使用B.selfadjointView().rankUpdate(A)会有所帮助(正如kennytm评论中所建议的那样)。

另一方面,当N = 3时,可能值得尝试延迟实现:

B = A.transpose().lazyProduct(A)

只是为了确定。 Eigen有内置的启发式方法来选择最佳的产品实现,但由于启发式方法必须简单快速地进行评估,因此可能并非100%正确。