Расположение в памяти структуры.структура массивов и массив структур в C / C ++ - PullRequest
36 голосов
/ 04 декабря 2011

В C / C ++ предположим, что я определяю простую структуру с именем point следующим образом.

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

Для конкретного экземпляра этой структуры скажем test A являются A.height, A.age, A.gender смежными в памяти?

В целом, как выглядят макеты в памяти для Структуры Массивов и Массива структур? Картина была бы действительно полезной.

Ответы [ 3 ]

63 голосов
/ 04 декабря 2011

Они не обязательно будут смежными в памяти.Это происходит из-за struct padding .

Однако, в вашем конкретном случае, он вполне может быть смежным.Но если вы изменили порядок на что-то вроде этого:

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

, то, скорее всего, не будет.Тем не менее, в вашем конкретном случае вы, вероятно, все равно получите заполнение после gender, чтобы выровнять структуру до 8 байт.


Разница между SoA ( Struct of Arrays )и AoS ( массив структур ) будет выглядеть следующим образом:

SoA:

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

AoS:

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

Обратите внимание, что панели AoS внутри каждой структуры.Хотя площадки SoA между массивами.

Они имеют следующие компромиссы:

  1. AoS , как правило, более читабельны дляпрограммист, так как каждый «объект» хранится вместе.
  2. AoS может иметь лучшую локальность кэша, если все члены структуры доступны вместе.
  3. SoA потенциально может быть более эффективным, поскольку группирование одних и тех же типов данных иногда приводит к векторизации.
  4. Во многих случаях SoA использует меньше памяти, потому что заполнение происходит только между массивами, а не между каждой структурой.
7 голосов
/ 04 декабря 2011

Отдельные поля являются смежными в том смысле, что между ними не будет храниться никаких других переменных. Они также гарантированно хранятся в указанном вами порядке. Но компилятор может свободно вставлять отступ между отдельными полями, например, чтобы выровнять вещи по границам слова. Итак, следующее:

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

может выглядеть в памяти так:

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

Что касается разницы между SoA и AoS, они выложены именно так, как вы можете себе представить.

0 голосов
/ 04 декабря 2011

Кроме стандартного отказа от ответственности «это зависит от вашей платформы, компилятора, бла-бла», да, height, age и gender будут непрерывными в памяти без заполнения между:

height|age|gender

Однако, если у вас есть массив test, каждый элемент массива будет иметь отступ между ними после каждого из gender, так что height следующего элемента будет правильно выровнен.

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

Если ваша цель состоит в том, чтобы использовать как можно меньше памяти, вам следует использовать «структуру массивов», поскольку она не использует заполнение.

|height0|height1|...

|age0|age1|...

|gender0|gender1|...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...