Вопрос по c++, c, memory, struct – Почему предпочтение выравнивания структуры данных?

5

Тип каждого элемента структуры обычно имеет выравнивание по умолчанию, т.е. каждый элемент структуры выравнивается по заранее определенной границе. По этой причине заполнение выполняется в следующем примере вики:

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
};



struct MixedData  /* After compilation in 32-bit x86 machine */
{
    char Data1; /* 1 byte */
    /* 1 byte for the following 'short' to be aligned on a 2 byte boundary 
assuming that the address where structure begins is an even number */
    char Padding1[1];
    short Data2; /* 2 bytes */
    int Data3;  /* 4 bytes - largest structure member */
    char Data4; /* 1 byte */
    char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */
};

Какова (практическая) причина того, что выравнивание должно быть сохранено?

Перейдите по этой ссылке. Это поможет вам понять, как выравнивание делает возможным быстрый доступ.geeksforgeeks.org/archives/9705 Manik Sidana
возможный дубликатWhy doesn't C++ make the structure tighter? Graham Borland

Ваш Ответ

3   ответа
8

ния двух соседних слов из памяти (а не только одного) и применения некоторой дополнительной побитовой арифметики для правильного выполнения назначенной операции.

Некоторые архитектуры, такие как x86, позволяют делать это с затратами на производительность. Другие архитектуры (прежде всего ARM), либо вызовут исключение (обычно приводящее кSIGBUS сигнал для пользовательского процесса) или даже «круглый» адрес до ближайшей границы, что может привести к очень неприятным ошибкам.

Кроме того, что важно для параллельного программирования, доступ без выравнивания не может быть сделан атомарным, в то время как выравнивание возможно.
2

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

Для 32-битных процессоров это 4 байта (или 32-битных), для 64-битных процессоров это 8 байтов.

Некоторые (не x86) процессоры будут генерировать ошибку, если вы попытаетесь получить доступ (скажем) к int, если он не выровнен по правильной границе.

Связь между различными устройствами является практической причиной сохранения выравнивания. При выравнивании по умолчанию эта структура будет иметь длину 24 байта, тогда как на 64-разрядном процессоре это будет 48 байтов, и ни один из элементов, кроме первого, не будет находиться в том же месте.

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

9

ять намного быстрее, чем их невыровненные аналоги.

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

Похожие вопросы