簡體   English   中英

使用Boost Interprocess在共享內存中的本征固定大小矩陣

[英]Eigen fixed-size matrices in shared memory using boost interprocess

我喜歡將本征固定大小的矩陣放入共享內存中。 但是在執行時,出現以下錯誤:

 /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使用帶有添加add_definitions(-DEIGEN_DONT_ALIGN) cmake的Eigen定義EIGEN_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;
}

如錯誤消息中提供的鏈接所示 ,您必須為eigen_vector使用內存對齊分配器,例如Eigen提供的內存分配器: Eigen::aligned_allocator

通過禁用與EIGEN_DONT_ALIGN對齊來解決此問題,也會禁用本征的顯式矢量化。 實際上,僅使用EIGEN_DONT_ALIGN_STATICALLY禁用靜態對齊就足夠了,在這種情況下,您僅對固定大小小的矩陣EIGEN_DONT_ALIGN_STATICALLY了向量化。 第三種甚至更好的選擇是使用非對齊類型:

typedef vector<Eigen::Matrix<double,2,1,Eigen::DontAlign>, eigen_allocator>             eigen_vector;

在這種情況下,您只能對這些對象進行向量化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM