Переупорядочивание инструкций в x86 / x64 asm-оптимизация производительности с помощью новейших процессоров


Сколько прироста производительности, если таковой имеется, можно получить от переупорядочивания инструкций x64 (x86-64) на последних высокопроизводительных процессорах Intel. Стоит ли беспокоиться об этом в чрезвычайно критических по времени ситуациях?

Меня также интересовала возможность получения прибыли за счет изменения использования регистров / использования дополнительных регистров (если они свободны) для обеспечения возможности перемещения кода на большие расстояния в некоторых нечетных случаях?

1 3

1 ответ:

Планирование команд обычно не имеет большого значения на коротких расстояниях, потому что обычно работает внеплановое выполнение. Это имеет гораздо большее значение на процессорах по порядку, таких как некоторые ядра ARM, где планирование нагрузок намного опережает инструкции, которые используют результат, - это большое дело.

Это может помочь некоторым даже на высокопроизводительных x86, хотя, в зависимости от того, какое узкое место ограничивает пропускную способность выполнения. См. http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ для некоторых интересный материал о том, что размер Роба в сравнении с количеством физических регистров является ограничивающим фактором во внепорядковом исполнении. Программное обеспечение-конвейеризация может помочь с длинными цепочками зависимостей, которые трудно скрыть при выполнении вне очереди.

Раннее включение инструкций в цепочку зависимостей критического пути может помочь, потому что планирование OOO обычно пытается выполнить самый старый-готовый-первый. (См. как именно запланированы x86 uops?).

Современные процессоры-это сложные животные., и иногда изменение порядка вещей может иметь значение, когда вы не ожидаете, что это будет иметь значение. Иногда невозможно точно угадать, почему это имело значение. Различное упорядочение может повлиять на пропускную способность переднего плана в декодерах или даже в кэше uop, поскольку существует много правил о том, как декодированные UOP упаковываются в строки до 6-uop в кэше uop (на процессорах Intel). Например, выравнивание ветвей для циклов, включающих микро-кодированные инструкции на Intel SnB-family Процессоры

Иногда объяснениеочень неясно. Например, в руководстве Intel по оптимизации, пример 3-25. Последовательность переупорядочивания для повышения эффективности инструкций MOV с нулевой задержкой, они обсуждают перезапись результата movzx с нулевой задержкой, чтобы быстрее освободить внутренний ресурс. (Я попробовал примеры на Haswell и Skylake и обнаружил, что mov-элиминация на самом деле работала значительно больше времени, когда делала это, но это на самом деле он был немного медленнее в общем цикле, а не быстрее. Пример должен был показать преимущество IvyBridge, которое, вероятно, узкие места на его 3 портах ALU, но HSW / SKL только узкое место на конфликтах ресурсов в цепочках dep и, кажется, не беспокоит необходимость порта ALU для большего количества инструкций movzx.)

Вероятно, это также относится к исключеннымmov инструкциям , а не только к movzx, но это может быть и не так.

IDK, если бы я это понял если бы я столкнулся с реальной ситуацией оптимизации (для IvyBridge), если бы руководство Intel не использовало ее в качестве примера. Счетчики производительности для uops issued vs executed (fused domain vs unfused-domain) показывают, сколько mov uops устранено, но выяснить, почему это происходит, было бы почти невозможно без руководства по оптимизации, в котором говорится что-то о причинах. Переупорядочивание соседних независимых инструкций просто для того, чтобы попробовать вещи, может помочь в качестве последнего шага в настройке, но в этот момент это вуду / черный магия / догадки.


Как отмечает Маргарет, есть причины для изменения порядка инструкций, помимо простого планирования. Смотрите руководстваagner Fog по оптимизации и микроархитектуре и другие ресурсы в вики-тегеx86 , чтобы узнать больше.

Например, группировка cmp/jcc и test/jcc вместе всегда является хорошей идеей из-за слияния макросов. Ваш компилятор сделает это за вас, когда вы будете компилировать с -march=haswell или чем-то еще, потому что это позволяет -mtune=haswell.

Это может также открыть uop другие возможности оптимизации, если это позволяет избежать некоторых mov инструкций или разлива / перезагрузки,но это выходит за рамки просто инструкций планирования.