Layout in memoria di una struttura. struttura di array e array di strutture in C / C ++

In C / C ++ suppongo di definire una semplice struttura denominata point come segue.

 struct test { double height; int age; char gender; } 

Per un’istanza specifica di questa struttura, i test A sono A.height, A.age, A.gender contigui in memoria?

Più in generale, come appaiono i layout in memoria per una struttura di array e una matrice di strutture? Un’immagine sarebbe davvero utile.

Non saranno necessariamente contigui nella memoria. Ciò è dovuto al riempimento della struttura .

Tuttavia, nel tuo caso particolare, potrebbe benissimo essere contiguo. Ma se hai cambiato l’ordine in qualcosa del genere:

 struct test { char gender; int age; double height; } 

quindi molto probabilmente non lo saranno. Tuttavia, nel tuo caso particolare, sarà comunque ansible ottenere padding dopo gender , per riallineare la struttura a 8 byte.


La differenza tra SoA ( Struct of Arrays ) e AoS ( Array of Structs ) sarebbe come questa:

SoA:

 ----------------------------------------------------------------------------------- | double | double | double | *pad* | int | int | int | *pad* | char | char | char | ----------------------------------------------------------------------------------- 

AoS:

 ----------------------------------------------------------------------------------- | double | int | char | *pad* | double | int | char | *pad* | double | int | char | ----------------------------------------------------------------------------------- 

Si noti che i pad AoS all’interno di ciascuna struttura. Mentre i pad SoA tra gli array.

Questi hanno i seguenti compromessi:

  1. AoS tende ad essere più leggibile per il programmatore dato che ogni “object” è tenuto insieme.
  2. AoS può avere una migliore localizzazione della cache se tutti i membri della struct sono accessibili insieme.
  3. SoA potrebbe potenzialmente essere più efficiente dal momento che raggruppare gli stessi tipi di dati insieme espone talvolta la vettorizzazione.
  4. In molti casi, SoA utilizza meno memoria perché il riempimento avviene solo tra gli array anziché tra ogni struttura.

I singoli campi sono contigui nel senso che non ci saranno altre variabili memorizzate tra loro. Sono inoltre garantiti per essere memorizzati nell’ordine dichiarato. Ma il compilatore è libero di inserire padding tra i singoli campi per allineare le cose ai confini delle parole, per esempio. Quindi il seguente:

 struct test { double height; char gender; int age; }; 

può assomigliare a questo in memoria:

  +7 +6 +5 +4 +3 +2 +1 +0 +---+---+---+---+---+---+---+---+ 0x0000 | height | +---+---+---+---+---+---+---+---+ 0x0008 | age | |gen| +---+---+---+---+---+---+---+---+ 

Per quanto riguarda la differenza tra SoA e AoS, sono disposti esattamente come potresti immaginare.

A parte il diniego standard di “dipende dalla tua piattaforma, compilatore, blahblahblah” … sì, height , age e gender saranno contigui nella memoria senza imbottiture intermedie:

height|age|gender

Tuttavia, se si dispone di un array di test , ciascun elemento dell’array avrà una spaziatura tra di essi dopo ciascun gender modo che l’ height dell’elemento successivo sia allineata correttamente.

|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...

Se il tuo objective è utilizzare la minor quantità ansible di memoria, allora dovresti usare la “struttura degli array” poiché non usa padding.

|height0|height1|...

|age0|age1|...

|gender0|gender1|...