Reputation: 2236
As you can see in the PointHVDIR
struct, it ends with a EIGEN_ALIGN16
.
#define PCL_ADD_UNION_POINT4D_HVD \
union EIGEN_ALIGN16 { \
float data[4]; \
struct { \
float h; \
float v; \
float d; \
}; \
};
struct PointHVDIR
{
PCL_ADD_POINT4D_HVD; // quad-word HVD
float intensity; ///< laser intensity reading
uint16_t ring; ///< laser ring number
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // ensure proper alignment
} EIGEN_ALIGN16;
What does it mean?
Upvotes: 0
Views: 1177
Reputation: 9678
This will be down to data structure alignment. It can be advantageous on some platforms to align a structure data to 16, 32 or 64bytes (so you can perform an aligned SIMD reads/writes). This is where the macros come in. From C++11 and onwards, you are able to use the alignas() operator to do this:
struct alignas(16) Vec4
{
float x,y,z,w;
};
However, prior to C++11 you had to use compiler specific extensions to align data types, e.g. with Visual C++:
struct __declspec(align(16)) Vec4
{
float x,y,z,w;
};
or with gcc/linux.
struct __attribute__((aligned(16))) Vec4
{
float x,y,z,w;
};
To work around that mess, most libraries will end up wrapping the variations in a macro:
#if __cplusplus >= 201103
# define ALIGN(X) alignas(x)
#elif defined(_MSC_VER)
# define ALIGN(X) __declspec(align(16))
#else
# define ALIGN(X) __attribute__((aligned(16)))
#endif
Which leads to a structure definition that looks like:
struct ALIGN(16) Vec4
{
float x,y,z,w;
};
In the case of the code above, since the outer PointHVDIR structure has been tagged as 16byte aligned, aligning the anonymous union as well is overkill. The code could be made more readable with:
#define PCL_ADD_UNION_POINT4D_HVD \
union { \
float data[4]; \
struct { \
float h; \
float v; \
float d; \
}; \
};
struct PointHVDIR
{
PCL_ADD_POINT4D_HVD;
float intensity;
uint16_t ring;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW //< ensure alignment when calling new
} EIGEN_ALIGN16; //< ensure alignment within structs, and on the stack.
Upvotes: 3
Reputation: 3938
This seems to be from the Eigen codebase? Some quick searching found the following.
From https://gitlab.com/libeigen/eigen/blob/master/Eigen/src/Core/util/ConfigureVectorization.h:
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
* However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
* so that vectorization doesn't affect binary compatibility.
*
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*
* FIXME: this code can be cleaned up once we switch to proper C++11 only.
*/
// (code defining EIGEN_ALIGN_TO_BOUNDARY and other things here...)
// Shortcuts to EIGEN_ALIGN_TO_BOUNDARY
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
#define EIGEN_ALIGN32 EIGEN_ALIGN_TO_BOUNDARY(32)
#define EIGEN_ALIGN64 EIGEN_ALIGN_TO_BOUNDARY(64)
In essence, it appears to be specifying that struct is aligned on a 16-byte boundary.
The union
in your example, then is not a union named EIGEN_ALIGN16
. Instead it's a #define
of an anonymous 16-byte-aligned union that is then included as a member of the struct.
Upvotes: 2