Should std :: vector comply with alignment (value_type)?

If I define a simple type with a specific alignment requirement, should the std::vector<t> specified type not have to comply with the alignment for each individual element?

Consider the following example.

 typedef std::array<double,3> alignas(32) avx_point; std::vector<avx_point> x(10); assert(!(std::ptrdiff_t(&(x[0]))&31) && // assert that x[0] is 32-byte aligned !(std::ptrdiff_t(&(x[1]))&31)); // assert that x[1] is 32-byte aligned 

I found that the alignment requirement silently (without any warning) is violated by clang 3.2 (with -stdlib=libc++ or without -stdlib=libc++ ), while gcc 4.8.0 gives a warning that it ignores the template argument attributes for std::vector (the intel compiler is too alignas to understand alignas , but if I __declspec(align(32)) using __declspec(align(32)) it will __declspec(align(32)) itself as clang). Both create code that launches the statement.

So is this the correct behavior or a clang (and icpc) error and a problem with gcc?

edit to answer the question raised in the comments: if I define

 typedef typename std::aligned_storage<sizeof (avx_point), alignof(avx_point)>::type avx_storage; 

I got

 sizeof (avx_storage) == 32; alignof(avx_storage) == 32; 

but std::vector<avx_storage> still cannot align the first element (and therefore all the others too) for clang and gcc (without warning this time). So, obviously, there are two problems with implementations: firstly, that std::allocator<type> ignores any alignment requirements even for the first element (invalid?), And secondly, that padding is not used to ensure alignment of subsequent elements .

------------

edit There is a related, more practical question on how to get memory appropriately aligned for SSE / AVX operations. In contrast, I want to know if std::vector<> (or std::allocator<> ) alignas according to the C ++ standard (as of 2011). None of the answers to this other question is a suitable answer to this.

+7
source share
1 answer

firstly, that std :: allocator ignores any alignment requirements even for the first element (illegal?)

I am far from being an expert on distributors, but it seems to me that this, unfortunately, is legal behavior. More specifically, the dispenser may ignore the requested alignment. Indeed, [allocator.requirements], 17.6.3.5/6 states:

If the alignment associated with a particular reconfigurable type is not supported by the allocator, creating an instance of the allocator for this type may fail. The distributor may also silently ignore the requested alignment .

You can write your own allocator to give you aligned memory. I did this before at my work, but unfortunately for copyright reasons I canโ€™t reveal the code :-( All I can say is the obvious thing: it was based on _aligned_malloc and _aligned_free (which are Microsoft extensions). Or you can use Google for a โ€œaligned allocatorโ€ and several options, one of which is

https://gist.github.com/donny-dont/1471329

I emphasize that I am not the author of this aligned distributor, and I have never used it.

Update

The aligned distributor is higher for Visual Studio / Windows, but it can be used as a base for implementing aligned distributors on other platforms. You can use the memalign family of functions or the C11 aligned_alloc function.

See this post.

+3
source

All Articles