2013-05-07 11 views
7

Se si definisce un tipo semplice con un determinato requisito di allineamento, non è necessario che lo std::vector<t> di tale tipo rispetti l'allineamento per ogni singolo elemento?dovrebbe std :: vector honor alignof (value_type)?

consideri il seguente esempio

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 

ho scoperto che il requisito di allineamento è silenzioso (senza alcun avviso) violati da clang 3.2 (con o senza -stdlib=libc++), mentre gcc 4.8.0 emette un avviso che ignora gli attributi sull'argomento modello a std::vector (il compilatore intel è troppo sciocco per comprendere alignas, ma se io uso invece __declspec(align(32)), si comporta come clang). Entrambi creano codice che fa scattare l'asserzione.

Quindi, questo comportamento corretto o un bug di clang (e icpc) e un problema con gcc?

modifica per rispondere a una questione sollevata nei commenti: se io definisco

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

ottengo

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

ma std::vector<avx_storage> non riesce ancora ad allineare il primo elemento (e quindi tutte le anche altri) per clang e gcc (senza preavviso questa volta). Quindi apparentemente ci sono due problemi con le implementazioni: in primo luogo, che std::allocator<type> ignora qualsiasi requisito di allineamento anche per il primo elemento (illegale?) E in secondo luogo, non viene applicata alcuna spaziatura per garantire l'allineamento degli elementi successivi.

+0

Fuori interesse, cosa succede se si confronta 'std :: vector >'? – Useless

risposta

3

primo luogo, che std :: allocator ignora i requisiti di allineamento, anche per il primo elemento (illegale?)

Sono ben lungi dall'essere un esperto su ripartitori, ma mi sembra che, purtroppo questo è un comportamento legale Più precisamente, un allocatore potrebbe ignorare l'allineamento richiesto. Infatti, [allocator.requirements], 17.6.3.5/6 stati:

Se l'allineamento associato a uno specifico tipo over-allineata non è supportato da un allocatore, istanziazione della allocatore per quel tipo può riuscire. L'allocatore può anche ignorare automaticamente l'allineamento richiesto.

È possibile scrivere il proprio allocatore per fornire memoria allineata. L'ho già fatto nel mio lavoro ma, sfortunatamente, per motivi di copyright, non posso rivelare il codice :-(Tutto quello che posso dire è la cosa ovvia: era basata su _aligned_malloc e _aligned_free (che sono estensioni di Microsoft). si può Google per "allocatore allineato" e alcune opzioni verrà in su, uno dei quali è

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

sottolineo che io non sono l'autore di questo allocatore allineato e non ho mai usato.

Aggiornamento

L'allocatore Allineati sopra è per Visual Studio/Windows, ma può essere utilizzato come base per l'attuazione allocatori allineati su altre piattaforme. È possibile utilizzare la famiglia di funzioni posix memalign o la funzione C11 aligned_alloc.

Vedere this post.

+1

Qual è la logica dello standard per introdurre le parole chiave 'alignas' e' alignof' solo per consentire agli allocatori di ignorarli? btw, ho il mio 'align_allocator <>', che funziona molto bene (e non ha stupidi problemi di copyright). – Walter

Problemi correlati