Сколько памяти использует выравнивание в C?

У меня есть эта программа:

__attribute__((section(".graph"))) __attribute__((aligned(16)))
uint16_t FLASH_BUFFER2[FLASH_SECTOR_SIZE];

int main ()
{
  printf("Hallo World"\n);
}

Когда я запускаю его, он резервирует FLASH_SECTOR_SIZE * 16 байта в памяти?

Редактировать: технически правильный вопрос: «Резервирует ли он FLASH_SECTOR_SIZE * 2 * 16 байт в памяти? (2 для uint16_t и 16 для выравнивания)»


person Tasos    schedule 21.11.2018    source источник
comment
хм, а где еще, по-твоему, это может быть?   -  person OznOg    schedule 21.11.2018
comment
У меня есть встроенная система с 1 МБ доступной оперативной памяти, FLASH_SECTOR_SIZE — это 65536. Так что это должно занять всю память. Они дали мне такой код, и мне интересно то же, что и вам, если честно.   -  person Tasos    schedule 21.11.2018
comment
Я предполагаю, что это сделано специально, память, безусловно, обрабатывается вручную в последнюю очередь. это, вероятно, потому, что у вас нет доступа к стандартным malloc/free (мне кажется)   -  person OznOg    schedule 21.11.2018
comment
Хм, я вижу 1 вызов malloc() в коде   -  person Tasos    schedule 21.11.2018
comment
очевидно, здесь их нет, но я полагаю, что это всего лишь демонстрационный образец ... в котором говорится, что я просто пытаюсь угадать, на плате должна быть какая-то документация, которую вы можете посмотреть, чтобы получить точную информацию.   -  person OznOg    schedule 21.11.2018
comment
Если вы выравниваете массив uint16_t по кратному 16 байтам, то он может быть перемещен на 14 байт (кратное 2) от того места, где он был бы размещен без директивы выравнивания. Это не большие накладные расходы и, по-видимому, не проблема, поскольку код будет (очевидно, обычно) работать, даже если он не будет выровнен по 16-байтовым границам. Вы добавили атрибут по какой-то причине, и экономия места не была одной из причин. И нет, он не резервирует FLASH_SECTOR_SIZE * 16 байта; он резервирует FLASH_SECTOR_SIZE * 2 байта (при условии, что CHAR_BIT == 8).   -  person Jonathan Leffler    schedule 21.11.2018
comment
Название вводило в заблуждение, а не то, что вы спрашиваете. На заметку: не используйте функции компилятора, когда есть стандартный способ. _Alignas в данном случае.   -  person too honest for this site    schedule 23.11.2018
comment
@toohonestforthissite кто-то изменил мой заголовок   -  person Tasos    schedule 24.11.2018
comment
Угадайте, кто и почему оставил комментарий? Я откатился. Пожалуйста, подумайте об этом, прежде чем редактировать снова.   -  person too honest for this site    schedule 24.11.2018
comment
@toohonestforthissite, пожалуйста, не меняйте его снова, я понятия не имею, что означает заголовок, который вы размещаете. Мой титул — мой честный вопрос.   -  person Tasos    schedule 25.11.2018
comment
Это явно не то, о чем вы спрашиваете в тексте и о чем ответы. В том числе тот, который вы приняли, который указывает, что мое редактирование было правильным. Поэтому я меняю его и буду признателен, если вы оставите его как есть. Заголовки должны быть максимально точными, чтобы помочь будущим пользователям найти нужную тему. Если вы не понимаете, что это значит, я рекомендую провести небольшое исследование в вашей любимой книге по C и прекрасном руководстве по gcc. Если у вас есть другой вопрос, не стесняйтесь задавать новый (вы не можете изменить свой вопрос после получения ответа). Изменить: я исправил очевидную опечатку.   -  person too honest for this site    schedule 25.11.2018


Ответы (2)


Нет. __attribute__((aligned(16))) просто гарантирует, что FLASH_BUFFER2 помещается на 16-байтовую границу. Он по-прежнему будет резервировать FLASH_SECTOR_SIZE * sizeof(uint16_t) байт.

Когда я использовал этот атрибут в прошлом, это было связано с тем, что контроллер DMA или механизм, используемый для записи во внутреннюю флэш-память и из нее, требовал, чтобы местоположение ОЗУ находилось на границе 16 байт. Поскольку вы делаете это во встроенной системе, вы можете иметь дело с тем же самым.

person contrapants    schedule 21.11.2018
comment
Он действительно используется для записи во флэш-память, и я понял, что причина та же. - person Tasos; 21.11.2018

Когда я запускаю его, он резервирует FLASH_SECTOR_SIZE * 16 байт в памяти?

Нет. Тип uint16_t имеет ширину 16 бит, а не 16 байт. Память действительно зарезервирована для массива, но ее размер составляет FLASH_SECTOR_SIZE * 2 байта.

Синтаксис __attribute__, который вы представляете, не является частью стандартного C, поэтому то, что он означает, зависит от вашего компилятора, но я не вижу причин думать, что он делает массив фактически не зарезервированным для него память в конце концов, или что он изменяет объем памяти зарезервировано. Вероятно, __attribute__((aligned(16))) просто гарантирует, что начальный адрес массива выровнен по 16-байтовой границе.

person John Bollinger    schedule 21.11.2018