gpt4 book ai didi

c++ - std::vector 的对齐问题

转载 作者:行者123 更新时间:2023-11-30 05:07:31 24 4
gpt4 key购买 nike

我终于遇到了这里描述的恼人问题: https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html

我有一个包含多个 Eigen 固定大小矩阵的结构,我想将我的结构的多个实例存储在一个 std::vector 中。很明显,“这些问题只出现在固定大小的可向量化 Eigen 类型和具有此类 Eigen 对象作为成员的结构中。”适用。但是,它只描述了如何解决 vector 直接收集特征对象的问题,而不是包含特征实例的结构。

目前我的问题是这样的:

struct MyStruct{
EIGEN_MAKE_ALIGNED_OPERATOR_NEW //Don't know if this applies here
Eigen::Matrix<double, 4, 4> A;
// several more instances and stuff here
MyStruct ( ...) // constructor taking several arguments, but only running an initilization list for some members

// no destructor defined / implemented !

// no methods!
}

//
MyStruct instanceStruct( .. constructing .. );
instanceStruct.A = someAssigment() ;
// this type of 'instancing' before i push it into the vector is necessary ...

std::vector<MyStruct> myVector;
myVector.push_back( std::move( instanceStruct ) ); // gdb tells me that here we run into a SIGSEGV

是什么导致了这个问题?谢谢!

最佳答案

从 C++17 开始

标准容器使用的默认分配器需要遵守对齐方式,任何存储持续时间 (*) 的变量也是如此。因此,在这种情况下,您的代码应该开箱即用,因为 Eigen 会在需要的地方指定对齐方式。

(*) 不过有一些注意事项:

  • 实现可能仍会抛出 bad_alloc 或拒绝编译请求不支持对齐的定义。但是,据我所知,它不会无提示地失败,也不会导致未定义的行为。

  • 允许用户定义的分配器默默地忽略过度对齐 类型。此外,请注意 C++17 之前的库可能会在内部做出假设,从而规避上述保证。通常,您应该始终检查任何设施分配类型(可能在内部)的过度对齐类型支持。

从 C++11 开始

您唯一(*)应该担心的是通过新分配器或默认分配器获取的动态存储持续时间的变量(有关更多详细信息,请参见 P0035r4)。

现在,Eigen 通过提供 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 和 Eigen::对齐_分配器:

struct MyStruct{
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // this will make new MyStruct to work
//...

// this will make vector (or any other allocator-aware container) to work
std::vector<MyStruct,Eigen::aligned_allocator<MyStruct> >

请注意,与官方文档所说的相反,您可以在 C++11 中使用任何对齐的分配器,因此不需要 #include<Eigen/StdVector> (如果在 C++11 之前的模式下编译,或者如果您的编译器不完全支持 C++11 对齐语义,则必须包含它)。

或者,您可以禁用矢量化(请参阅 Eigen 宏文档以了解如何操作)或仅通过 new 分配可矢量化矩阵:

struct MyStructImpl{
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
// vectorizable matrices ...
};

struct MyStruct
{
MyStructImpl* aligned_data_; // possibly a unique_ptr<MyStructImpl>
// copy-move-assign accordingly ...
// non-vectorizable matrices and other data ...
};

std::vector<MyStruct> v; // ok !

这将花费你一个堆分配和更少的内存局部性,但会降低移动 MyStruct 的成本。因此,结果可能会更快或更慢,具体取决于您的用例。

关于c++ - std::vector 的对齐问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47364311/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com