c++ - Eigen3:如何在性能关键操作中访问矩阵系数?
问题描述
我正在尝试优化依赖 Eigen3 的 C++ 中的关键操作。我不清楚哪种类型的系数访问操作会导致运行时性能成本,或者编译器什么时候才能做好。为了找出我困惑的根源,我在下面发布了一个以几种不同方式实现的示例,以及每种方式的一些假设。
这里还有一些细节:
- 矩阵M将在整个程序的大部分时间保持不变
- critical_function确实被调用了很多次,这就是它被内联的原因
有人可以澄清哪种方法在性能方面是最好的吗?我可能对引用、取消引用等的影响成本感到困惑。
选项 1:直接访问矩阵系数
#include <Eigen/Dense>
class A{
A(){
// Assume M has the right numbers
}
// This function will be called many many times, inside loops
inline void critical_function()
{
// Do many operations using M(1, 1), for example:
double y = 1 / M(1, 1);
// ... some more code using M(1, 1)
}
private:
Eigen::Matrix3d M;
};
假设:
- M(1,1) 导致不断取消引用,产生成本,因为循环将被添加到计算偏移量(这不是一个数组,但不清楚编译器如何管理它)
选项 2:创建我们关心的系数的副本
#include <Eigen/Dense>
class A{
A(){
// Assume M has the right numbers
x = M(1, 1);
}
// This function will be called many many times, inside loops
inline void critical_function()
{
// Do many operations using x, for example:
double y = 1 / x;
// ... some more code using x
}
private:
double x;
Eigen::Matrix3d M;
};
假设:
- 访问x比访问M(1, 1)产生更少的周期,因此它比选项 1 更可取。
- x确实包含与M(1,1)相同的值,但存在确保此数据重复的重要风险,因此代码维护需要避免这种情况。
选项 3:利用参考资料
#include <Eigen/Dense>
class A{
A(){
// Assume M has the right numbers
}
// This function will be called many many times, inside loops
inline void critical_function()
{
auto & x = M(1, 1);
// Do many operations using x, for example:
double y = 1 / x;
// ... some more code using x
}
private:
Eigen::Matrix3d M;
};
假设:
- 与在函数范围内不断引用M(1,1)相比,具有单个引用x将产生更少的循环。
- 这种潜在的优化仅在critical_function内部产生影响,但不会在外部范围内延续,例如多次调用函数的循环。
编辑
类型已更正为双精度(从 int 或 float),以与 Matrix3d 保持一致。
解决方案
简而言之,不要打扰和写M(1,1)
。
如果您正在处理编译时矩阵(如Matrix3d
编译时已知的索引),那么所涉及的索引计算M(1,1)
将被任何编译器完全优化掉。换句话说,以下两个片段将生成相同的程序集:
struct A {
Matrix3d M;
void foo() { double x = M(1,1); }
};
struct A {
double a, b, c, d, e, f, g, h, i;
void foo() { double x = e; }
};
所以选项 2 会更糟,选项 3 也可能因为引入指针而降低性能。
推荐阅读
- bash - 如何确定bash中字符串中分组数字的数量
- arrays - React.JS - 使用数据在图像数组中创建循环限制
- vba - 修改文档目录的内容控制属性的宏
- html - Web HTML 游戏无法在三星电视 HG32EE590 上运行
- javascript - ionic 3 - 离子项目点击不起作用
- python - 我可以知道 recursive=true 是什么意思吗?
- angular - 如何更改密码连同用户的用户更改?
- asp.net - 如何通过上传 .exe 文件在 Azure 上托管控制台应用程序?
- javascript - 用 JavaScript 上传空的 excel 文件
- c# - 我需要帮助来显示我的折线图