ti-enxame.com

Layout na memória de uma estrutura. estrutura de matrizes e matriz de estruturas em C/C++

Em C/C++, suponha que eu defina um struct simples chamado point como segue. 

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

Para uma instância específica dessa estrutura, diga que test A são A.height, A.age, A.gender contiguous Na memória? 

Mais geralmente, como os layouts na memória para uma estrutura de matrizes e uma matriz de estruturas se parecem? Uma foto seria realmente útil. 

36
smilingbuddha

Eles não serão necessariamente contíguos na memória. Isso ocorre devido ao struct padding .

No entanto, no seu caso particular, pode muito bem ser contíguo. Mas se você mudou a ordem para algo como isto:

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

então eles provavelmente não serão. No entanto, no seu caso particular, você provavelmente receberá preenchimento após gender, para realinhar a estrutura para 8 bytes.


A diferença entre SoA ( Struct of Arrays ) e AoS ( Array of Structs ) seria assim:

SoA:

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

AoS:

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

Observe que os pads do AoS dentro de cada estrutura. Enquanto SoA pads entre os arrays.

Estes têm os seguintes trade-offs:

  1. AoS tende a ser mais legível para o programador à medida que cada "objeto" é mantido unido.
  2. AoS pode ter melhor localidade de cache se todos os membros da estrutura forem acessados ​​juntos.
  3. SoA poderia ser mais eficiente já que agrupar os mesmos tipos de dados às vezes expõe a vetorização.
  4. Em muitos casos SoA usa menos memória porque o preenchimento é apenas entre matrizes e não entre todas as estruturas.
62
Mysticial

Os campos individuais são contíguos no sentido de que não haverá outras variáveis ​​armazenadas entre elas. Eles também são garantidos para serem armazenados na ordem que você declarou. Mas o compilador é livre para inserir preenchimento entre os campos individuais para alinhar as coisas aos limites do Word, por exemplo. Então, o seguinte:

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

pode se parecer com isso na memória:

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

Quanto à diferença entre SoA e AoS, eles são expostos exatamente como você pode imaginar.

7
Oliver Charlesworth

Além do aviso padrão de "depende da sua plataforma, compilador, blahblahblah" ... sim, height, age e gender será contíguo na memória sem preenchimento entre:

height|age|gender

No entanto, se você tiver uma matriz de test, cada elemento da matriz terá preenchimento entre eles após cada gender, de modo que a height do próximo elemento seja alinhada corretamente.

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

Se o seu objetivo é usar a menor quantidade de memória possível, então você deve ir com "estrutura de arrays", já que não usa padding.

|height0|height1|...

|age0|age1|...

|gender0|gender1|...

0
Jim Buck