Выравнивание памяти на современных процессорах?

Даже для локальных переменных, зная, что это объявляется, финал означает, что я не должен волноваться о ссылке, изменяемой позже. Это означает, что при отладке и я вижу, что переменная позже, я уверен, что она относится к тому же объекту. Это - то меньше вещи, о которой я должен волноваться при поиске ошибки. Премия то, что, если 99% переменных объявляются финалом, то несколько переменных, которые действительно являются переменными, выделяются лучше. Кроме того, финал позволяет компилятору найти некоторые более возможные глупые ошибки, которые могли бы иначе остаться незамеченными.

12
задан Michael 6 December 2009 в 17:06
поделиться

4 ответа

Это зависит от множества факторов. Если вы обращаетесь к пиксельным данным только по одному байту за раз, выравнивание не будет иметь никакого значения в подавляющем большинстве случаев. Для чтения / записи одного байта данных большинство процессоров вообще не заботится о том, находится ли этот байт на границе 4 байта или нет.

Однако, если вы обращаетесь к данным в единицах, превышающих один байт (скажем, в 2-х или 4-х байтовых единицах), то вы обязательно увидите эффекты выравнивания. Для некоторых процессоров (например, для многих процессоров RISC) доступ к невыровненным данным на определенных уровнях является совершенно незаконным: попытка прочитать 4-байтовое слово с адреса, который не выровнен по 4-байтовому адресу, вызовет исключение доступа к данным (или исключение хранилища данных). ) на PowerPC, например.

На других процессорах (например, x86) доступ к невыровненным адресам разрешен, но это часто приводит к скрытому снижению производительности. Загрузка / сохранение памяти часто реализуются в микрокоде, и микрокод обнаруживает невыровненный доступ. Обычно микрокод выбирает правильное 4-байтовое количество из памяти, но если он не выровнен, ему придется извлечь два 4-байтовых ячейки из памяти и восстановить нужное 4-байтовое количество из соответствующего байты двух мест. Очевидно, что выборка двух ячеек памяти медленнее, чем одна.

Это только для простых загрузок и запоминаний. Некоторые инструкции, например, в наборах инструкций MMX или SSE, требуют, чтобы их операнды памяти были правильно выровнены. Если вы попытаетесь получить доступ к невыровненной памяти с помощью этих специальных инструкций, вы увидите что-то вроде исключения недопустимой инструкции.

Подводя итог, я бы не стал особо беспокоиться о выравнивании, если вы не пишете код, критичный для производительности ( например в сборке). Компилятор очень помогает, например, заполняя структуры так, чтобы 4-байтовые величины были выровнены по 4-байтовым границам, а на x86 процессор также помогает вам при работе с невыровненными обращениями. Поскольку пиксельные данные, с которыми вы имеете дело, имеют размер 3 байта, вы почти всегда будете выполнять однобайтовый доступ.

Если вы решите, что вместо этого хотите получать доступ к пикселям в единичных 4-байтовых доступах (в отличие от 3-х однобайтовых обращений), было бы лучше использовать 32-битные пиксели и выровнять каждый отдельный пиксель по 4-байтовому граница. Выравнивание каждой строки по 4-байтовой границе, но не каждого пикселя, будет иметь небольшой эффект, если он вообще есть.

Основываясь на вашем коде, я предполагаю, что это связано с чтением формата файла растрового изображения Windows - файлы растровых изображений требуют длины каждой строки сканирования должно быть кратно 4 байтам, поэтому настройка буферов данных пикселей с этим свойством имеет свойство, которое вы можете просто прочитать во всем растровом изображении одним махом в свой буфер (конечно, вам все равно придется иметь дело с тот факт, что строки развертки хранятся снизу вверх, а не сверху вниз, и что данные пикселей - это BGR вместо RGB). В этом нет большого преимущества,

7
ответ дан 2 December 2019 в 21:23
поделиться

Да, выравнивание действительно влияет на производительность современных - скажем, x86 - процессоров. Как правило, загрузка и хранение данных происходит на естественных границах трассы; если вы получаете 32-битное значение в регистр, это будет быстрее всего, если оно уже выровнено по 32-битной границе. Если это не так, x86 «позаботится об этом за вас» в том смысле, что процессор по-прежнему будет выполнять нагрузку, но для этого потребуется значительно большее количество циклов, потому что возникнут внутренние споры, чтобы « повторно выровняйте доступ.

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

Но особенно с большими буферами однородных данных, которые получают доступ случайным образом и где производительность в совокупности действительно важна, как в вашем пиксельном буфере выше выравнивание структур данных по-прежнему может быть полезным.

Обратите внимание, что в приведенном выше примере выравнивается только каждая «строка» пиксельных данных. Сами пиксели по-прежнему имеют длину 3 байта и часто не выровнены внутри «строк», так что особой пользы здесь нет. Например, существуют форматы текстур, которые содержат 3 байта реальных данных на пиксель и буквально тратят лишний байт на каждый из них, чтобы данные были выровнены.

Здесь есть более общая информация: http: / /en.wikipedia.

4
ответ дан 2 December 2019 в 21:23
поделиться

Выравнивание буфера оказывает влияние. Вопрос в том, насколько это заметно? Ответ может быть очень специфичным для приложения . В архитектурах, которые изначально не поддерживают невыровненный доступ - например, 68000 и 68010 (68020 добавляет невыровненный доступ) - это действительно проблема производительности и / или обслуживания, поскольку ЦП откажет или, возможно, перехватит обработчик для выполнения невыровненного доступа .

Идеальное выравнивание для различных процессоров можно оценить: 4-байтовое выравнивание подходит для архитектур с 32-битным трактом данных. 8-байтовое выравнивание для 64-битных. Однако кэширование L1 имеет эффект . Для многих процессоров это 64 байта, хотя в будущем он, несомненно, изменится.

Слишком большое выравнивание (то есть восемь байт, где требуется только два байта) не приводит к снижению производительности для любой более узкой системы, даже на 8-битном микроконтроллере. Он просто тратит (потенциально) несколько байтов памяти.

Ваш пример довольно своеобразен: 3-байтовые элементы имеют 50% шанс индивидуального невыровненного (до 32 бит), поэтому выравнивание буфера кажется бессмысленным - по крайней мере по соображениям производительности. Однако в случае массовой передачи всего этого он оптимизирует первый доступ. Обратите внимание, что невыровненный первый байт также может повлиять на производительность при передаче на видеоконтроллер.

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

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

1
ответ дан 2 December 2019 в 21:23
поделиться
  • Does aligning a buffer like this have a performance impact on modern processors?

Yes. For instance if memcpy is optimized using SIMD instructions (like MMX/SSE) some operations will be faster with aligned memory. In some architectures there are (processor) instructions that fail if the data is not aligned, thus something might work on your machine but not in another one.

With aligned data you also make a better use of the CPU caches.

  • Should I be worrying about alignment at all, or will the compiler handle this?

I should worry about alignment when I use dynamic memory and the compiler cannot handle this (see the reply to this comment).

For other stuff in your code you have the -malign flag and aligned attribute to play with.

1
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

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