It looks like using Eigen types with STL containers is very messy and requires special attention to alignment issues. My problem is that I'm planning to create complex class hierarchy with dozens of classes that might include one or more Eigen types as member variables. From the documentation it appears that as soon as you include Eigen type in member variables, your class gets "infected" with same issues as Eigen types. This means I've to take extra care for using STL containers not only for Eigen types but also for all of my dozens of classes.
Even more worse part that worries me is that anyone who uses instances of my classes in their code will have same issues and would be needed to be expert on this subject - even if my classes didn't expose any Eigen types in their public interface!
This is quite frustrating. Questions I have,
Yes your understanding is mostly correct, but I should add that this only concerns Eigen's fixed size types that require alignment such as Vector4f
, Matrix2d
, etc. but not Vector3f
or MatrixXd
. Moreover, the core of the problem is that STL containers do not honor alignas
requirements yet, though this should come in some future C++ version.
I think that the easiest way to avoid such difficulties is to use non-aligned Eigen's types for class members and container value-types such as:
typedef Eigen::Matrix<float,4,1,Eigen::DontAlign> UVector4f;
typedef Eigen::Matrix<double,2,2,Eigen::DontAlign> UMatrix2d;
This way you do not have to bother about alignment issues, and you won't loose explicit vectorization. In Eigen 3.3, unaligned objects are vectorized too.
EDIT:
Regarding your last question, unfortunately, there is no possibility in C++ to detect such a shortcoming at compile time. If assertions are not disabled and that an invalid unaligned allocation occurs at runtime, then you will get an explicit assertions message, but that's all we can do. Therefore, if your program runs fine on a given system with some given compilation flags, then this does not mean that your code is safe. For instance, on most 64 bits systems buffer are aligned on 16 bytes boundary and so, if you do not enable AVX instruction set, then your code will run fine. On the other hand, the same code may assert if moving to a more exotic platform, or enabling AVX instructions that required 32 bytes alignment by default. Nonetheless, static analysers are becoming more and more powerful, and I think that some of such issue could be detected by them.
Another strategy consists in checking your program with a custom malloc
returning 8 bytes aligned buffers only. This way you should be able to catch all shortcomings, assuming your program is well covered by unit tests. To do so, you must compile with -DEIGEN_MALLOC_ALREADY_ALIGNED=0
, for obvious reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With