优化自己的表达
Optimize eigen expression
我正在尝试优化这个乘法的代码:
A += s * (C + (D-U) * (D-U).transpose());
其中 s
是标量,C
是矩阵(通常为 10x10),D
和 U
是向量。我试过:
A.noalias() += s * (C + (D-U) * (D-U).transpose());
但我认为阅读还不够docs。在 eigen 中优化此表达式的最佳方法是什么?
首先将 D-U
计算为一个临时向量,这样它只计算一次,然后,由于您的向量很小,请尝试将 *
替换为 .lazyProduct(...)
。更准确地说,你最终会得到:
auto DU = (D-U).eval();
A.noalias() += s * (C + DU.lazyProduct(DU.transpose()));
当然,您必须在启用完整编译器优化的情况下准确地对每个更改进行基准测试,以查看它们是否真的有效并且不会适得其反。
最后,如果 A
和 C
是对称的,您可能只想更新 A 的一半。这对于大型矩阵(例如 >200x200)是有意义的,但是由于您的矩阵非常小,这会适得其反,因为逻辑开销和 SIMD 效率较低。
我正在尝试优化这个乘法的代码:
A += s * (C + (D-U) * (D-U).transpose());
其中 s
是标量,C
是矩阵(通常为 10x10),D
和 U
是向量。我试过:
A.noalias() += s * (C + (D-U) * (D-U).transpose());
但我认为阅读还不够docs。在 eigen 中优化此表达式的最佳方法是什么?
首先将 D-U
计算为一个临时向量,这样它只计算一次,然后,由于您的向量很小,请尝试将 *
替换为 .lazyProduct(...)
。更准确地说,你最终会得到:
auto DU = (D-U).eval();
A.noalias() += s * (C + DU.lazyProduct(DU.transpose()));
当然,您必须在启用完整编译器优化的情况下准确地对每个更改进行基准测试,以查看它们是否真的有效并且不会适得其反。
最后,如果 A
和 C
是对称的,您可能只想更新 A 的一半。这对于大型矩阵(例如 >200x200)是有意义的,但是由于您的矩阵非常小,这会适得其反,因为逻辑开销和 SIMD 效率较低。