2015-07-06 22 views
5

così ho letto che quando le variabili sono dichiarate in C++, se si vuole ottenere la cache ottimale legge la memoria deve attenersi al suo allineamento naturale. Esempio:C++ allineamento memoria

int a; // memory address should end in 0x0,0x4,0x8,0xC 
int b[2]; // 8 bytes 0x0,0x8 
int b[4]; // 16 bytes 0x0 

Ma in pratica queste variabili non seguono le regole "allineamento naturale", una variabile di 16 byte risiedeva in un indirizzo di memoria che si è conclusa in 0xC. Perchè è questo ?

+3

array non sono interessati da allineamento, solo i singoli elementi sono – Quentin

+0

potrebbe desiderare di sito il caso esatto –

+0

Non c'è nessun caso davvero im solo sperimentando, tutto quello che ho trovato è stato che, indipendentemente dalle dimensioni variabili tutto era sempre 4 byte allineato a meno che non fosse un tipo di dati da 1 byte. Solo curioso di sapere perché. – Student123

risposta

4

allineamento memoria naturale si riferisce generalmente all'allineamento delle singole variabili, non array di variabili. Quindi una matrice di numeri interi a 4 byte (come apparentemente avete sopra) è naturalmente allineata a un limite di 4 byte e non al limite di 16 byte.

L'allineamento della memoria naturale di solito riguarda il modo in cui le istruzioni di carico/archivio della CPU sono progettate e implementate, non la dimensione delle linee della cache. La CPU non carica interi array alla volta (ad eccezione dei carichi vettoriali). Quindi la CPU non si preoccupa veramente se un intero che sta caricando fa parte di un array o meno.

I carichi vettoriali, che caricano piccoli array allo stesso tempo, spesso hanno requisiti di allineamento più rigidi. Ad esempio, per eseguire un caricamento vettoriale allineato su un x86, l'elemento deve essere allineato a 16 byte.

+0

Ho anche provato con 16 tipi di dati byte byte che non erano ancora allineati a 0x0. Tutto quello che posso dire è che tutto è allineato a 4 byte indipendentemente dalle dimensioni. Alcuni compilatori farebbero CPU diverse o diverse? – Student123

1

v'è alcuna garanzia di allineamento

+0

Dovrebbe essere un commento. – scohe001

+1

@LegalizeIt è la risposta completa, OP ha affermato che l'allineamento dovrebbe essere qualcosa, ho affermato che non ci sono garanzie. Il resto della risposta è stato dato nel 1 ° commento. Un int può avere un indirizzo che è strano, probabilmente non lo farà, ma può farlo. –

+0

@ scohe001 è una risposta –

2

C++ non si allineerà nulla sulla linea di cache, perché per tutti gli effetti che non conosce c'è una cache.

Se si desidera qualcosa allineato su un limite di 16 byte, provare posix_memalign() per le cose nell'heap o (se si utilizza GCC) nello stack, int x __attribute__ ((aligned (16))). In C++ 11 c'è lo alignas specifier.

Non conosco un modo per chiamare lo new() con un allineamento garantito.

+0

È possibile scrivere il proprio operatore 'new()' e applicare l'allineamento –

+0

Ho ragione nel dire che, mentre un blocco di memoria è allineato a 4 byte, la CPU farà sempre il massimo dai dati e non devi fare più di una lettura per ottenere una variabile da 4 byte? – Student123

+0

@ Student123 Immagino che questo dipenda dalla CPU. Direi che in generale è una buona regola da seguire. So che le moderne microarchitetture x86 non penalizzano più i carichi non allineati. – hayesti

0

Secondo Intel® 64 e IA-32 Architetture ottimizzazione manuale di riferimento (sezione B.4.5.2 Assist),

32 byte istruzioni AVX negozio che si estendono su due pagine richiedono un assist che costa circa 150 cicli.