it-swarm.com.de

Layout einer Struktur. Struktur von Arrays und Arrays von Strukturen in C/C++

Angenommen, ich definiere in C/C++ eine einfache Struktur namens point wie folgt. 

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

Für eine bestimmte Instanz dieser Struktur heißt test AA.height, A.age, A.gender zusammenhängend Im Speicher? 

Wie sehen die Layouts im Speicher für eine Struktur von Arrays und ein Array von Strukturen allgemeiner aus? Ein Bild wäre wirklich hilfreich. 

36
smilingbuddha

Sie sind im Gedächtnis nicht unbedingt zusammenhängend. Dies liegt an struct padding .

In Ihrem speziellen Fall kann es jedoch sehr gut zusammenhängend sein. Aber wenn Sie die Reihenfolge in etwas geändert haben:

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

dann werden sie höchstwahrscheinlich nicht sein. In Ihrem speziellen Fall werden Sie jedoch nach gender wahrscheinlich noch aufgefüllt, um die Struktur auf 8 Bytes auszurichten.


Der Unterschied zwischen SoA ( Struktur von Arrays ) und AoS ( Array von Strukturen ) würde folgendermaßen aussehen:

SoA:

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

AoS:

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

Beachten Sie, dass AoS-Pads in jeder Struktur enthalten sind. Während SoA-Pads zwischen den Arrays.

Diese haben folgende Kompromisse:

  1. AoS ist für den Programmierer tendenziell besser lesbar, da jedes "Objekt" zusammengehalten wird.
  2. AoS hat möglicherweise eine bessere Cache-Lokalität, wenn auf alle Mitglieder der Struktur gemeinsam zugegriffen wird.
  3. SoA könnte potenziell effizienter sein, da durch Gruppieren derselben Datentypen manchmal die Vektorisierung sichtbar wird.
  4. In vielen Fällen verwendet SoA weniger Speicher, da das Auffüllen nur zwischen Arrays und nicht zwischen jeder Struktur erfolgt.
62
Mysticial

Die einzelnen Felder sind in dem Sinne zusammenhängend, dass zwischen ihnen keine anderen Variablen gespeichert sind. Sie werden auch garantiert in der von Ihnen angegebenen Reihenfolge gespeichert. Dem Compiler steht es jedoch frei, zwischen den einzelnen Feldern eine Auffüllung einzufügen, um z. B. Dinge an Word-Grenzen auszurichten. Also das Folgende:

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

kann in der Erinnerung so aussehen:

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

Der Unterschied zwischen SoA und AoS ist genau so angelegt, wie Sie sich vielleicht vorstellen.

7

Abgesehen von dem Standard-Haftungsausschluss von "es hängt von Ihrer Plattform, dem Compiler, dem Blahblahblah ab" ... ja, height, age und gender werden im Speicher zusammenhängend sein, ohne dass dazwischen ein Auffüllen erfolgt:

height|age|gender

Wenn Sie jedoch ein Array von test haben, wird jedes Array-Element nach jedem gender zwischen sich aufgefüllt, so dass das height des nächsten Elements richtig ausgerichtet ist.

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

Wenn Sie möglichst wenig Speicher verwenden möchten, sollten Sie auf die Struktur der Arrays zurückgreifen, da keine Auffüllung verwendet wird.

|height0|height1|...

|age0|age1|...

|gender0|gender1|...

0
Jim Buck