2016-02-12 18 views
6

voglio overalign mio tipo su un limite di cache, quindi ho usato alignas:alignas parola chiave non rispettati

struct alignas(64) W { }; 

Questo compila bene. Ma poi, con mia sorpresa, quando cerco di assegnare un gruppo di W s, non sono di 64 byte allineati, ma in realtà a 16 byte allineati:

#include <iostream> 
#include <iomanip> 
#include <unordered_map> 

struct alignas(64) W { }; 

int main() { 
    std::unordered_map<int, int> offset; 

    for (int i = 0; i < 1000; ++i) { 
     auto w = new W; 
     offset[(uintptr_t)w % 64]++; 
    } 

    for (const auto& p : offset) { 
     std::cout << p.first << ' ' << p.second << '\n'; 
    } 
} 

Resa:

0 250 
16 250 
32 250 
48 250 

su diverse compilazioni (gcc 4.8.2, gcc 5.2.0, clang 3.7.1). Che cosa succede? Ho detto di allineare, perché non si sta allineando?

+5

["È definito dall'implementazione se i tipi sovraallineati sono supportati (\ [basic.align \])."] (Http://eel.is/c++draft/expr.new#1). Vedi anche [numero CWG 2130] (http://wg21.link/cwg2130). –

+1

@ T.C. Sembra che dovrebbe essere una risposta. – NathanOliver

+0

@ T.C. Come faccio a sapere se un'implementazione lo supporta (apparentemente né gcc né clang do) – Barry

risposta

3

Questo si risponde bene qui: https://stackoverflow.com/a/16510895

Fondamentalmente: new (almeno nella sua normale utilizzo) garantisce solo un massimo costante allineamento (alignof(std::max_align_t)) per ogni chiamata a new.

2

L'altra risposta è corretta nel senso che spiega la limitazione esistente, ma vorrei sottolineare che le cose stanno per migliorare.

Come indicato da T.C. nei commenti, questa era una carenza di vecchia data nella lingua. È looks come the WG effort risolvere questo ha portato a una risoluzione in C + + 17 (che ha appena raggiunto lo stato di funzionalità completa). Pertanto, durante la compilazione dello standard, l'overalling verrà finalmente rispettato dall'allocazione dinamica, utilizzando i nuovi overload std::align_val_t di new. Così risolvendo il problema di Barry!

Data la quantità di nuovi ponteggi richiesto, presumo che non sarà backported alle versioni precedenti dello standard, in modo che il vecchio avvertimento sulla loro allocazione dinamica bastando solo per i tipi che hanno allineamento fondamentale presumibilmente restare fedele.