使用带有STL容器的特征类型和std :: vector

时间:2016-12-11 14:06:30

标签: c++ c++11 vectorization eigen eigen3

看起来使用带有STL容器的Eigen类型非常混乱,需要特别注意对齐问题。我的问题是我计划用几十个类创建复杂的类层次结构,这些类可能包含一个或多个Eigen类型作为成员变量。从文档中可以看出,只要在成员变量中包含Eigen类型,您的类就会被感染"与本征类型相同的问题。这意味着我要特别注意使用STL容器,不仅要用于Eigen类型,还要用于我所有的几十个类。

更让我担心的更糟糕的是,任何在我们的代码中使用我的类实例的人都会遇到同样的问题而且需要成为这方面的专家 - 即使我的课程没有公开任何Eigen类型在他们的公共界面!

这非常令人沮丧。我有问题,

  1. 我的理解是否正确(我只需要支持C ++ 11和现代编译器)?
  2. 是否有人使用任何模式,因此他们不必通过特殊的特征处理来污染他们的代码?
  3. 我正考虑全局禁用整个矢量化。这会以牺牲性能为代价解决上述问题吗?是否可以仅针对特定代码选择性地启用它?
  4. 如果我忘记在代码中的某处处理对齐问题,我是否总是遇到编译时错误或问题可能仍然隐藏在运行时可能会崩溃?

1 个答案:

答案 0 :(得分:4)

是的,你的理解大多是正确的,但我要补充一点,这只涉及需要对齐的Eigen固定大小类型,例如Vector4fMatrix2d等,但不是Vector3f或{ {1}}。此外,问题的核心是STL容器尚未满足MatrixXd要求,尽管这应该在未来的C ++版本中出现。

我认为避免此类困难的最简单方法是对类成员和容器值类型使用非对齐的Eigen类型,例如:

alignas

通过这种方式,您不必担心对齐问题,也不会忽略显式向量化。在Eigen 3.3中,未对齐的对象也被矢量化。

修改

关于你的上一个问题,不幸的是,C ++中没有可能在编译时检测到这样的缺点。如果未禁用断言并且在运行时发生无效的未对齐分配,那么您将获得显式的断言消息,但这就是我们所能做的。因此,如果您的程序在给定系统上运行时带有一些给定的编译标志,那么这并不意味着您的代码是安全的。例如,大多数64位系统缓冲区在16字节边界上对齐,因此,如果您不启用AVX指令集,那么您的代码将运行正常。另一方面,如果移动到更奇特的平台,或者启用默认需要32字节对齐的AVX指令,则相同的代码可以断言。尽管如此,静态分析仪正变得越来越强大,我认为其中一些问题可以被它们检测出来。

另一种策略在于使用自定义typedef Eigen::Matrix<float,4,1,Eigen::DontAlign> UVector4f; typedef Eigen::Matrix<double,2,2,Eigen::DontAlign> UMatrix2d; 检查程序,仅返回8字节对齐的缓冲区。这样你应该能够发现所有的缺点,假设你的程序被单元测试很好地覆盖了。为此,您必须使用malloc进行编译,原因很明显。