0. Eigen的内存对齐
Eigen使用了内存对齐以实现计算加速,目前遇到过以下问题:
- Eigen的断言报错,如
data is not aligned
- 直接段错误异常退出
1. 解决方法
1.1 使用Release编译模式和屏蔽架构优化
G2O的仓库issue中提到了以下两个要点:
- 使用
Release
模式进行编译:无论是编译第三库(如G2O)还是引用该库的应用程序,建议在CMakeLists.txt中注明为Release
模式 - 如CMakeLists.txt中使用了架构优化
-march=native
,务必去掉!
具体CMakeLists.txt可如下填写
set(CMAKE_BUILD_TYPE Release)
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
视觉SLAM十四讲第二版实践操作遇到的问题也佐证了需要使用Release版本
1.2 C++编译器版本
有几篇博客均提到编译器的版本会影响Eigen的编译,因此尽可能使用新版本的编译器如C++17
Explanation of the assertion on unaligned arrays:
There are 4 known causes for this issue. If you can target [c++17] only with a recent compiler (e.g., GCC>=7, clang>=5, MSVC>=19.12), then you’re lucky: enabling c++17 should be enough (if not, please report to us).
1.3 代码层面对Eigen的使用
如有下面几种情况请注意:
- 包含Eigen对象的结构体:将
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
宏放在类的公共部分 - STL容器或手动内存分配:为容器提供Eigen的内存分配器
//下面的容易导致内存不对齐而出错:
std::map<int, Eigen::Vector4d>
//应向STL提供内存分配器:
std::map<int, Eigen::Vector4d, std::less<int>,
Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4d>>>
- 按值传递Eigen对象:应该改用 引用 传递
- 使用了全局或静态的 Eigen 对象: Eigen官方不建议使用 全局或静态 对象,它的内存对齐操作更多在 堆内存 中使用
详看下面两篇文章:
1.4 终极武器
禁用内存对齐!
非迫不得已尽可能不要使用,因为禁用内存对齐将大大降低性能,具体做法自行百度