2015-01-21 37 views
0

我喜欢将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与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

由于按照错误消息中提供的link时解释,你必须使用一个内存分配器排列为eigen_vector,例如通过本征提供的一个:Eigen::aligned_allocator

通过禁用与​​EIGEN_DONT_ALIGN的对齐解决此问题也禁用特征的显式矢量化。事实上,仅在EIGEN_DONT_ALIGN_STATICALLY时禁用静态对齐就足够了,在这种情况下,您只能释放小型固定大小矩阵的向量化。第三个,甚至更好的选择是使用非取向型:

在这种情况下,您量化宽松仅这些对象
typedef vector<Eigen::Matrix<double,2,1,Eigen::DontAlign>, eigen_allocator>    eigen_vector; 

+0

谢谢,但没有人知道boost :: interprocess :: allocator是否足够好? 我想知道未来我的方法会不会有麻烦? – Max 2015-01-21 16:47:31

+0

我的编辑应该回答你的问题,尽管一切都已经在我之前粘贴的链接中解释过。 – ggael 2015-01-21 22:52:17