转载:https://blog.youkuaiyun.com/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成员
如果你代码中有这样的形式
-
class Foo -
{ -
//... -
Eigen::Vector2d v; -
//... -
}; -
//... -
Foo *foo = new Foo;
那么需要将 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 插入到代码中。即
-
class Foo -
{ -
... -
Eigen::Vector2d v; -
... -
public: -
EIGEN_MAKE_ALIGNED_OPERATOR_NEW -
}; -
... -
Foo *foo = new Foo;
详情请见Eigen官网对此的解释:http://eigen.tuxfamily.org/dox-devel/group__TopicStructHavingEigenMembers.html
2.SLT容器或手动分配内存
如果代码中出现这种形式:
-
std::vector<Eigen::Matrix2f> my_vector; -
struct my_class { ... Eigen::Matrix2f m; ... }; -
std::map<int, my_class> my_map;
需要利用Eigen::aligned_allocator重新对齐。比如
std::map<int, Eigen::Vector4f>
需要改为
-
std::map<int, Eigen::Vector4f, std::less<int>, -
Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4f> > >
如果是std::vector,则还需要引用头文件#include <Eigen/StdVector>。例如
-
#include<Eigen/StdVector> -
/* ... */ -
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);
同样如果结构体中有这样的应用,也需要进行相应的修改
-
struct Foo -
{ -
Eigen::Vector2d v; -
}; -
void my_function(const Foo& v);
详情请见:http://eigen.tuxfamily.org/dox-devel/group__TopicPassingByValue.html
4.编译器在堆栈对齐中做出错误的假设
如果代码形如:
-
void foo() -
{ -
Eigen::Quaternionf q; -
//... -
}
解决方法分为local solution 和global solution。
local solution:
-
__attribute__((force_align_arg_pointer)) void foo() -
{ -
Eigen::Quaternionf q; -
//... -
}
详情: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优化后与代码发生了冲突。
博客介绍了在使用PLSLAM时遇到的Eigen库内存对齐错误,错误源于Eigen库为利用SSE加速而要求特定内存对齐。作者列举了官网给出的四种可能原因,并逐一排查,包括结构体中包含Eigen成员、STL容器或手动分配内存、通过Eigen对象传递函数参数以及编译器堆栈对齐问题。经过修改代码和CMake设置,问题最终得到解决,怀疑是由于gcc优化导致的冲突。
17万+

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



