C++ Eigen Matrix clarifications
Asked Answered
N

2

7

I have only recently started exploring C++ Eigen library and a little puzzled with some of the documentation. It would be great if someone can clarify this.

  1. In the common pitfalls (https://eigen.tuxfamily.org/dox-devel/TopicPitfalls.html) Alignment Issues section, it says " Indeed, since C++17, C++ does not have quite good enough support for explicit data alignment.".

    The page on how to get rid of alignment issues (https://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html#getrid), the documentation says, "If you can target [c++17] only with a recent compiler (e.g., GCC>=7, clang>=5, MSVC>=19.12), then you're lucky: enabling c++17 should be enough" .

    So is alignment not an issue with Eigen Matrix if I am using c++ 17 with gcc>=7.0? Have I understood this right? And that the macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW won't be needed? And if this is correct, what is different between c++14/c++17 which takes care of the alignment issues?

  2. The second question is regarding the pass-by-value section (https://eigen.tuxfamily.org/dox-devel/group__TopicPassingByValue.html). The documentation claims that pass-by-value could be illegal and could crash the program. This is very puzzling to me. Wouldn't pass-by-value just invoke a copy constructor? As an example.

Eigen::Vector3f veca = ComputeVecA();
Eigen::Vector3f vecb = veca; //< If pass-by-value is unsafe, is this operation safe?
  1. And lastly, can I rely on RVO/NRVO for Eigen fixed sized matrix class? I suspect the answer to this is yes.
Nataline answered 3/8, 2019 at 19:36 Comment(5)
For what concerns alignment, C++17 has a new version of operator new that is used when the alignment requirements exceeds the default used by the operator: en.cppreference.com/w/cpp/memory/new/operator_new , see e.g. (3). But yeah, I agree with you, the documentation seems to be contradicting itself (I'm not a native speaker, maybe you understand it better than me)Earnestineearnings
For the passing by value there is this discussion that might be useful: #10019728Earnestineearnings
@CuriouslyRecurringThoughts: It's not your English; I'm a native speaker and the first quote from the Eigen site is nonsense. The use of "since" implies that before C++17, there was support for it, and that support was somehow removed. They probably meant "until".Gerontology
@NicolBolas thanks. At least I'm not alone in the confusionEarnestineearnings
Looking at github.com/eigenteam/eigen-git-mirror/blob/master/Eigen/src/…, it seems to me that alignment is not an issue in c++17. But I am still not clear on (2).Nataline
C
2
  • Q1: as already commented, this was a typo when updating this paragraph for c++17. This is already fixed.

  • Q2: I don't remember all the details about this one but it is related to two technical issues.

    1. Some compilers failed to properly align the stack, in this case it is hopeless to get aligned function parameters.
    2. Old ABI specifications did not allowed overalignment of function parameters. I would expect that since c++11 and the usage of the standardized alignas keyword this is not an issue anymore, but maybe this is still a problem on some exotic compiler-OS combinations.
  • Q3: there is nothing preventing RVO/NRVO, and from my experience when it can apply it does apply.

Calfskin answered 5/8, 2019 at 8:0 Comment(0)
S
3

In the common pitfalls (https://eigen.tuxfamily.org/dox-devel/TopicPitfalls.html) Alignment Issues section, it says "Indeed, since C++17, C++ does not have quite good enough support for explicit data alignment."

This seems to be a typo. It should say "until C++17" instead of "since C++17" because C++17 actually added support for allocation with extraordinary alignment restrictions. Two comments agree with me.

The page on how to get rid of alignment issues (https://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html#getrid), the documentation says, "If you can target [C++17] only with a recent compiler (e.g., GCC >= 7, Clang >= 5, MSVC >= 19.12), then you're lucky: enabling C++17 should be enough."

So is alignment not an issue with Eigen Matrix if I am using C++17 with gcc >= 7.0? Have I understood this right? And that the macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW won't be needed?

Yes.

And if this is correct, what is different between C++14/C++17 which takes care of the alignment issues?

C++17 supports Dynamic memory allocation for over-aligned data. operator new now properly allocates over-aligned memory with the align_val_t argument.

The second question is regarding the pass-by-value section (https://eigen.tuxfamily.org/dox-devel/group__TopicPassingByValue.html). The documentation claims that pass-by-value could be illegal and could crash the program. This is very puzzling to me. Wouldn't pass-by-value just invoke a copy constructor?

If the variable is a local variable (as vecb in your example), then the compiler and the library take care to ensure that vecb meets the special alignment restriction required by Eigen. However, if the variable is a function parameter, this alignment restriction is not respected, meaning the program may operate on ill-aligned memory, thus crash. (This has little to do with the copy constructor.)

And lastly, can I rely on RVO/NRVO for Eigen fixed sized matrix class? I suspect the answer to this is yes.

The answer is pretty much the same for Eigen classes and other classes: try and see. Usually the answer is yes.

Sevenfold answered 4/8, 2019 at 0:38 Comment(6)
` However, if the variable is a function parameter, this alignment restriction is not respected`, Why? How exactly is pass-by-value any different than copy construction of a local var? Why would the compiler respect alignment in one case and not another?Nataline
@Nataline Well, I actually never thought of that ;-) The documentation actually does not mention that. As far as I know, Eigen uses compiler extensions to ensure alignment restriction, and function parameters are special in some way, but I may need a person familiar with this to answer this question.Sevenfold
"However, if the variable is a function parameter, this alignment restriction is not respected, meaning the program may operate on ill-aligned memory, thus crash." Can you provide the part of the C++ specification where it's legal for a function parameter to not be aligned as required by alignas? Because as far as I can tell, if you alignas a type, then every instance of that type (which is not dynamically allocates) must be aligned as specified in the alignas specification.Gerontology
@NicolBolas The problem is that Eigen doesn't use alignas. It uses compiler-specific stuff.Sevenfold
@L.F. Eigen does use alignas when available, which should be the default for most users.Calfskin
@Calfskin Wow, is that so. Well, then I don't really have an idea what is going on either :(Sevenfold
C
2
  • Q1: as already commented, this was a typo when updating this paragraph for c++17. This is already fixed.

  • Q2: I don't remember all the details about this one but it is related to two technical issues.

    1. Some compilers failed to properly align the stack, in this case it is hopeless to get aligned function parameters.
    2. Old ABI specifications did not allowed overalignment of function parameters. I would expect that since c++11 and the usage of the standardized alignas keyword this is not an issue anymore, but maybe this is still a problem on some exotic compiler-OS combinations.
  • Q3: there is nothing preventing RVO/NRVO, and from my experience when it can apply it does apply.

Calfskin answered 5/8, 2019 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.