【转载】运行PLSLAM时,遇到Eigen对齐问题

博客介绍了在使用PLSLAM时遇到的Eigen库内存对齐错误,错误源于Eigen库为利用SSE加速而要求特定内存对齐。作者列举了官网给出的四种可能原因,并逐一排查,包括结构体中包含Eigen成员、STL容器或手动分配内存、通过Eigen对象传递函数参数以及编译器堆栈对齐问题。经过修改代码和CMake设置,问题最终得到解决,怀疑是由于gcc优化导致的冲突。
摘要由CSDN通过智能技术生成

转载:https://blog.csdn.net/wojiushixiangshi/article/details/78356271

 

对于PLSLAM已经编译成功,运行时报错:

 

 

plslam_dataset: /usr/include/eigen3/Eigen/src/Core/DenseStorage.h:128: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions,
 32>::plain_array() [with T = double; int Size = 16; int MatrixOrArrayOptions = 0]: Assertion `(reinterpret_cast<size_t>(eigen_una
ligned_array_assert_workaround_gcc47(array)) & (31)) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-
devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.

 

 


(作者在Apr 6, 2018的更新中修复了这个问题,添加了EIGEN_MAKE_ALIGNED_OPERATOR_NEW命令)

 


 

 

google原因为:Eigen库为了使用SSE加速,所以内存分配上使用了128位的指针,但实际分配的可能时64位或32位。

 

查询EIGEN提示的网页,官网给出了四种原因,如下。

 

 

1.结构体中包含Eigen成员

 

如果你代码中有这样的形式

 
  1. class Foo

  2. {

  3. //...

  4. Eigen::Vector2d v;

  5. //...

  6. };

  7. //...

  8. Foo *foo = new Foo;

那么需要将 EIGEN_MAKE_ALIGNED_OPERATOR_NEW  插入到代码中。即

 
  1. class Foo

  2. {

  3. ...

  4. Eigen::Vector2d v;

  5. ...

  6. public:

  7. EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  8. };

  9. ...

  10. Foo *foo = new Foo;

详情请见Eigen官网对此的解释:http://eigen.tuxfamily.org/dox-devel/group__TopicStructHavingEigenMembers.html

 

2.SLT容器或手动分配内存

 

如果代码中出现这种形式:

 
  1. std::vector<Eigen::Matrix2f> my_vector;

  2. struct my_class { ... Eigen::Matrix2f m; ... };

  3. std::map<int, my_class> my_map;

需要利用Eigen::aligned_allocator重新对齐。比如

std::map<int, Eigen::Vector4f>

需要改为

 
  1. std::map<int, Eigen::Vector4f, std::less<int>,

  2. Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4f> > >

 

如果是std::vector,则还需要引用头文件#include <Eigen/StdVector>。例如

 
  1. #include<Eigen/StdVector>

  2. /* ... */

  3. std::vector<Eigen::Vector4f,Eigen::aligned_allocator<Eigen::Vector4f> >

官网给出了另外一种解决办法,详情请见:http://eigen.tuxfamily.org/dox-devel/group__TopicStlContainers.html

 

 

3.通过Eigen目标像function传值

比如

void my_function(Eigen::Vector2d v);

需要改成

void my_function(const Eigen::Vector2d& v);

同样如果结构体中有这样的应用,也需要进行相应的修改

 
  1. struct Foo

  2. {

  3. Eigen::Vector2d v;

  4. };

  5. void my_function(const Foo& v);

详情请见:http://eigen.tuxfamily.org/dox-devel/group__TopicPassingByValue.html

 

4.编译器在堆栈对齐中做出错误的假设

如果代码形如:

 
  1. void foo()

  2. {

  3. Eigen::Quaternionf q;

  4. //...

  5. }

解决方法分为local solution 和global solution。

local solution:

 
  1. __attribute__((force_align_arg_pointer)) void foo()

  2. {

  3. Eigen::Quaternionf q;

  4. //...

  5. }

详情:http://eigen.tuxfamily.org/dox-devel/group__TopicWrongStackAlignment.html

 


 

 

按照第一、第二,我对代码进行了修改,但是问题依然没有解决。于是查看CMakelists.txt,有一行:

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -O3 -mtune=native -march=native")-march=native")

将-march=native删除.得到

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -O3 -mtune=native ")

问题成功解决。

猜测可能是gcc优化后与代码发生了冲突。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值