Eigen EIGEN_MAKE_ALIGNED_OPERATOR_NEW 的传递效果?

Cat*_*ree 6 c++ memory-alignment new-operator eigen

最近,我意识到的潜在问题内存对齐固定大小的矢量化的本征对象

文档所述的正确代码:

class Foo
{
  ...
  Eigen::Vector2d v;
  ...
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
 
...
 
Foo *foo = new Foo;
Run Code Online (Sandbox Code Playgroud)

我想知道这个代码是否可以?

class Foo2
{
  ...
  Foo foo;
  ...
};
 
...
 
Foo2 *foo = new Foo2; //?
Run Code Online (Sandbox Code Playgroud)

还是应该EIGEN_MAKE_ALIGNED_OPERATOR_NEWFoo2类中再次添加?这就是建议在这里我想:

如果我们添加 EIGEN_MAKE_ALIGNED_OPERATOR_NEW,这只能解决 Cartographer 库本身的问题。该库的用户还必须将 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 添加到包含矢量化 Cartographer 类的类中。这听起来像是一场维护噩梦。

我没有新运算符重载的经验。我认为这个问题更笼统,并且以某种方式与 new 运算符在 C++ 中的工作方式有关。例如,重载的 new 运算符 inFoo是否被默认的 new 运算符 in 调用Foo2?继承呢?如果Foo2从继承Foo,要我们把同样EIGEN_MAKE_ALIGNED_OPERATOR_NEWFoo2


由于我最近才知道这个话题,我做了很多研究,发现如下:

  • x86-64 上的默认对齐是 16 字节,所以没有也没关系EIGEN_MAKE_ALIGNED_OPERATOR_NEW(如果只启用了 SSE)
  • 除非您的代码是为更新的 SIMD 集编译的(例如 AVX2-march=native在本地计算机上进行所有优化),否则EIGEN_MAKE_ALIGNED_OPERATOR_NEW现在需要
  • 其他架构呢?例如对于 ARM,如果我们不声明EIGEN_MAKE_ALIGNED_OPERATOR_NEW并且启用了 NEON ,会有什么问题吗?
  • 我发现建议使用template <typename Scalar> using Isometry3 = Eigen::Transform<Scalar, 3, Eigen::Isometry | Eigen::DontAlign>而不是Isometry
  • 仍然需要考虑如何能够Isometry3d在没有对齐问题的情况下轻松地在代码中使用特征类型(例如)。那么添加一个MyIsometry3d继承自的新类型Eigen::Transform<double, 3, Eigen::Isometry | Eigen::DontAlign>

更一般地说,我想在固定大小的特征类型中“禁用对齐”(或矢量化):

  • 我想保留语法,例如保留Isometry3d在代码中
  • 并且Isometry3d在课堂上使用或使用时不会被对齐问题所困扰std::vector<Isometry3d>
  • 告诉 Eigen 总是使用未对齐的加载/存储(例如_loadu_/_storeu_对于 x86-64 内在函数,其他架构怎么样,是否有等效的?)所有固定大小的 Eigen 类型?
  • 否则只需禁用固定大小特征类型的矢量化,因为我认为在使用矢量化指令和这些类型的 C++ 代码之间惩罚应该(几乎)为空
  • 所以我想解决方案是使用#define EIGEN_UNALIGNED_VECTORIZE 0,对吗?所以我必须#define在任何Eigen/Dense包含之前把它放在任何地方?
  • 我不想用类似的东西Matrix<double,2,2,DontAlign>或一个新的类替换任何地方

最后,查看固定大小的可矢量化特征对象页面,我认为缺少某些类型。对于我使用的类型:

  • Eigen::Isometry3d, Eigen::Isometry3f?
  • Eigen::AngleAxisd, Eigen::AngleAxisf?

oar*_*ish 2

我在 Eigen 邮件列表上询问了这个问题,一位维护者说这个宏的需求确实是可传递的。Foo2因此也需要宏。

更新:实际上这似乎是不正确的,因为它operator new是从基类继承的。