Выравнивание машинного кода

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

Я надеялся реализовать процедуру автоматического выравнивания, которая может обрабатывать код целиком и вставлять выравнивание в соответствии со спецификацией ЦП (ширина строки кэша, 32/64 бита и т. д.)...

Кто-нибудь может подсказать по поводу этой процедуры? Например, целевым ЦП может быть 64-разрядная платформа ЦП Intel Core i7.

Спасибо.


person Sergei    schedule 07.03.2011    source источник


Ответы (4)


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

Однако я хотел бы указать вам на сайт Agner Fog и руководства по оптимизации для создатели компиляторов, которых вы можете найти там. Они содержат множество информации по таким темам — строки кэша, прогнозирование ветвлений и выравнивание данных/кода.

person Martin    schedule 07.03.2011
comment
+1 за упоминание Agner Fog. Дополнительно хочу отметить, что на этот вопрос нет однозначного ответа - все зависит от архитектуры, от размера кода и размера кеша, от предсказуемости ветвей, поэтому выравнивания по спецификации нет. - person Gunther Piez; 07.03.2011
comment
Да, думал об этом, однако похоже, что некоторые эффекты я могу исключить, например, неверное предсказание переходов и выравнивание данных. В моих тестах у меня точно такой же ввод данных и ветвление. Единственное, что я сделал, это вставил разные инструкции по выравниванию в разные места кода. Так, например, код без какого-либо выравнивания работает за 50 нс, затем выравнивание по ветвям может сбрить 4 нс, поэтому у меня тогда 46 нс, а вставка в некоторые определенные места (просто эксперимент) может сбрить снова 2 нс. А иногда слишком большое мировоззрение снижает его до 50 или даже хуже... - person Sergei; 07.03.2011
comment
Этот блок кода будет выполняться много раз и определяет общую пропускную способность, поэтому даже сокращение его выполнения на 5 нс в конце будет вполне измеримым. Спасибо, что указали на Агнера, я уже знаю об этом, но так и не нашел конкретных предложений по правильному выравниванию кода. - person Sergei; 07.03.2011

Выравнивание по абзацам (16 байт) обычно является лучшим. Однако это может привести к тому, что некоторые "локальные" JMP-инструкции перестанут быть локальными (из-за увеличения размера кода). Также может привести к кэшированию меньшего количества кода. Я бы выравнивал только основные сегменты кода, я бы не выравнивал каждый крошечный раздел подпрограммы/JMP.

person Brian Knoblauch    schedule 07.03.2011

Однако не эксперт... Переходы к местам, которые не будут находиться в кеше инструкций, должны больше всего выиграть от выравнивания, потому что вы будете читать всю строку кеша инструкций, чтобы заполнить конвейер. Учитывая это утверждение, прямые ветки выиграют при первом запуске функции. Обратные ветки (например, циклы for и while), вероятно, не принесут пользы, поскольку цель ветки и последующие инструкции уже считаны в кеш. Следуйте ссылкам в ответе Мартина.

person phkahler    schedule 07.03.2011

Как упоминалось ранее, это очень сложная область. Agner Fog кажется хорошим местом для посещения. Что касается сложностей, я наткнулся здесь на статью Torbjörn Granlund об "Улучшенном делении инвариантными целыми числами". " и в коде, который он использует для иллюстрации своего нового алгоритма, первая инструкция - я думаю - основная метка - nop - нет операции. Согласно комментарию, это значительно улучшает производительность. Иди разберись.

person Olof Forshell    schedule 08.03.2011
comment
Спасибо за ресурс - там довольно интересные статьи. Похоже, это просто выравнивание пункта назначения ветки. - person Sergei; 09.03.2011
comment
К сожалению, г-н Гранлунд никогда не раскрывал свои методы выжимания из процессора максимума — по крайней мере, те, о которых я знаю. Его программа GMPLIB может вас заинтересовать, хотя бы для изучения использования его инструкций. Это математическая библиотека произвольной точности, которая, среди прочего, использовалась для вычисления сотен миллионов десятичных знаков числа пи (gmplib.org). Его сводка в формате PDF о задержках инструкций для каждого семейства процессоров также очень информативна. - person Olof Forshell; 09.03.2011