Transitive effect of Eigen EIGEN_MAKE_ALIGNED_OPERATOR_NEW?

Stack Overflow Asked by Catree on December 7, 2020

Recently, I was made aware of the potential issues of memory alignment for Fixed-size vectorizable Eigen objects.

The correct code as stated in the doc:

class Foo
  Eigen::Vector2d v;
Foo *foo = new Foo;

I would like to know if this code is ok or not?

class Foo2
  Foo foo;
Foo2 *foo = new Foo2; //?

Or should EIGEN_MAKE_ALIGNED_OPERATOR_NEW be again added in the Foo2 class?
This is what is suggested here I think:

If we were to add EIGEN_MAKE_ALIGNED_OPERATOR_NEW this would only solve the problem for the Cartographer library itself. Users of the library would also have to add EIGEN_MAKE_ALIGNED_OPERATOR_NEW to classes containing vectorized Cartographer classes. This sounds like a maintenance nightmare.

I have no experience with new operator overloading. I think the question is more general and would somehow be related to how new operator works in C++. For instance is the overloaded new operator in Foo be called by the default new operator in Foo2? What about inheritance? If Foo2 inherits from Foo, should we put also EIGEN_MAKE_ALIGNED_OPERATOR_NEW in Foo2?

Since I was only aware of this topic recently, I did many research and found the following:

  • default alignment on x86-64 is 16 bytes, so it is fine to not have EIGEN_MAKE_ALIGNED_OPERATOR_NEW (if only SSE is enabled)
  • unless your code is compiled for more recent SIMD sets (e.g. AVX2 with -march=native to have all the optimizations on a local computer), EIGEN_MAKE_ALIGNED_OPERATOR_NEW is now needed
  • what about the other architecture? For instance for ARM, any issue if we don’t declare EIGEN_MAKE_ALIGNED_OPERATOR_NEW and NEON is enabled?
  • I found suggestion to use template <typename Scalar> using Isometry3 = Eigen::Transform<Scalar, 3, Eigen::Isometry | Eigen::DontAlign> instead of Isometry
  • still need to think on how to be able to easily use Eigen type (e.g. Isometry3d) in the code without the alignment issue. So add a new type MyIsometry3d that inherits from Eigen::Transform<double, 3, Eigen::Isometry | Eigen::DontAlign> for instance?

More generally, I would like to "disable alignment" (or vectorization) in fixed-size Eigen type:

  • I would like to keep the syntax, for instance keeping Isometry3d in the code
  • and not be bothered with alignment issue when using Isometry3d in a class or when using std::vector<Isometry3d>
  • something to tell Eigen to always use unaligned load/store (e.g. _loadu_/_storeu_ for x86-64 intrinsics, what about the other architecture, is there an equivalent?) for all fixed-size Eigen type?
  • else just disable vectorization for fixed-size Eigen type since I believe penalty should be (almost) null between using vectorized instructions and just C++ code for these types
  • so I guess the solution is to use #define EIGEN_UNALIGNED_VECTORIZE 0, is it correct? So I have to put this #define everywhere before any Eigen/Dense include?
  • I don’t want to replace everywhere with something like Matrix<double,2,2,DontAlign> or a new class

Finally, looking at Fixed-size vectorizable Eigen objects page, I think some types are missing. For the types I am using:

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP