问题描述
当用户代码和库代码没有同时使用编译选项 -march=native时,在运行时经常会报 double free error或者其他的内存相关错误。但是在某些时候,这个编译选项又不会带来错误。
经过更多测试,发现这个问题发生在接口类存在Eigen数组作为成员变量的时候。因此需要对这个问题进行原理理解。
太长不看(解决方法)
接口类当中的eigen成员变量都声明不做对齐,这样就解决了用户代码和库编译时指令集加速方式不一致时带来的不同对齐方式的冲突。如,使用Eigen::Matrix<float, 2, 1, Eigen::DontAlign> 取代Eigen::Vector2f
Eigen内存对齐
eigen内存需要额外的对齐,进而才能使用eigen调用的各类加速指令集等。因此,动态、静态的eigen矩阵,包含eigen的结构体、类,都需要额外的对齐命令才能正常工作(构造、运算、析构)。
详情见:
http://eigen.tuxfamily.org/dox/group__DenseMatrixManipulation__Alignement.html
目前影响我们的部分有:
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW 与 C++17:C++17中,自动对包含eigen类、结构体的构造函数进行对齐的操作,因此 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 宏此时为空
- 固定大小的eigen矩阵默认会进行16位对齐(有指令集加速时表现可能不一致!!!见下一节)
- 作为类成员变量的动态大小的eigen矩阵不影响类本身的构造和析构;但是动态大小的eigen矩阵本身的构造和析构仍然有自己的对齐问题(见指令集加速)
- 将eigen矩阵传值进入函数是非常不好的方式。效率和内存正确性都可能受影响。建议使用常量引用、Eigen::Ref或者Eigen::Map等复制成本极低的方式

最低0.47元/天 解锁文章
7742

被折叠的 条评论
为什么被折叠?



