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;
...
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
...
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 ofIsometry
- 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 typeMyIsometry3d
that inherits fromEigen::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 usingstd::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 anyEigen/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
?