我喜欢将Eigen固定大小的矩阵放入共享内存中。 但在执行时我收到以下错误:
/usr/include/eigen3/Eigen/src/Core/DenseStorage.h:78:
Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 16>::plain_array()
[with T = double; int Size = 2; int MatrixOrArrayOptions = 0]:
Assertion `(reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & 0xf) == 0 &&
"this assertion is explained here: "
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html"
" **** READ THIS WEB PAGE !!! ****"' failed.
Aborted (core dumped)
使用带有EIGEN_DONT_ALIGN
的cmake使用Eigen定义add_definitions(-DEIGEN_DONT_ALIGN)
解决了我的问题,但我想知道问题出现了什么以及缺点是什么。
有我的例子:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/algorithm/string.hpp>
#include <Eigen/Dense>
using namespace boost::interprocess;
using namespace boost::container;
typedef managed_shared_memory::segment_manager segment_manager_t;
typedef scoped_allocator_adaptor<allocator<void, segment_manager_t> > void_allocator;
typedef void_allocator::rebind<Eigen::Matrix<double,2,1>>::other eigen_allocator;
typedef vector<Eigen::Matrix<double,2,1>, eigen_allocator> eigen_vector;
class CheckPoints {
public:
bool valid;
eigen_vector points;
typedef void_allocator allocator_type;
//Since void_allocator is convertible to any other allocator<T>, we can simplify
//the initialization taking just one allocator for all inner containers.
CheckPoints ( const allocator_type &void_alloc )
: valid ( true ), points ( void_alloc ) {}
CheckPoints ( CheckPoints const& other, const allocator_type &void_alloc )
: valid ( other.valid ), points ( other.points, void_alloc ) {}
friend std::ostream &operator << ( std::ostream &os, const CheckPoints &o ) {
os << o.valid;
for ( size_t i = 0; i < o.points.size(); i++ )
os << ", <" << o.points[i] ( 0,0 ) << ", " << o.points[i] ( 1,0 ) << ">";
return os;
}
};
typedef void_allocator::rebind<CheckPoints>::other checkpoints_allocator;
typedef vector<CheckPoints, checkpoints_allocator> checkpoints_vector;
class Trajectories {
public:
Trajectories ( const void_allocator &void_alloc )
: trajectory ( void_alloc )
{}
Eigen::Matrix<double,2,1> base;
checkpoints_vector trajectory;
friend std::ostream &operator << ( std::ostream &os, const Trajectories &o ) {
os << "base: " << o.base << std::endl;
for ( size_t i = 0; i < o.trajectory.size(); i++ ) os << o.trajectory[i] << std::endl;
return os;
}
};
int main ( int argc, char **argv ) {
using namespace boost::interprocess;
//Remove shared memory on if called with c or clear
if ( argc > 1 && (boost::iequals ( "clear", argv[1] ) || boost::iequals ( "c", argv[1] ) ) ) {
std::cout << "Remove shared memory" << std::endl;
shared_memory_object::remove ( "MySharedMemory" );
}
//Create shared memory
managed_shared_memory segment ( open_or_create,"MySharedMemory", 16*1024*1024 );
//An allocator convertible to any allocator<T, segment_manager_t> type
void_allocator alloc_inst ( segment.get_segment_manager() );
Trajectories *trajectories = segment.find_or_construct<Trajectories> ( "Trajectories" ) ( alloc_inst );
if ( trajectories->trajectory.size() != 10 ) {
std::cout << "Create Data" << std::endl;
trajectories->trajectory.resize ( 10 );
for ( size_t i = 0; i < trajectories->trajectory.size(); i++ ) {
trajectories->trajectory[i].points.resize ( i+1 );
for ( size_t j = 0; j < trajectories->trajectory[i].points.size(); j++ ) {
trajectories->trajectory[i].points[j] ( 0,0 ) = j*2;
trajectories->trajectory[i].points[j] ( 1,0 ) = j*2+1;
}
}
} else {
std::cout << "Data Exists" << std::endl;
}
std::cout << *trajectories << std::endl;
}
答案 0 :(得分:0)
正如在错误消息中提供的link之后所解释的那样,您必须为eigen_vector
使用内存对齐的分配器,例如Eigen提供的分配器:Eigen::aligned_allocator
。
通过禁用与EIGEN_DONT_ALIGN
的对齐来解决此问题也会禁用Eigen的显式向量化。实际上,仅使用EIGEN_DONT_ALIGN_STATICALLY
禁用静态对齐就足够了,在这种情况下,您只会松散小固定大小矩阵的矢量化。第三种甚至更好的选择是使用非对齐类型:
typedef vector<Eigen::Matrix<double,2,1,Eigen::DontAlign>, eigen_allocator> eigen_vector;
在这种情况下,您只会松开这些对象的矢量化。