Условный ход (cmov) в компиляторе G CC - PullRequest
1 голос
/ 01 февраля 2020

Я где-то видел, что компилятор G CC может иногда предпочитать не использовать условный mov при преобразовании моего кода в ASM.

В каких случаях он может выбрать что-то другое, кроме условного mov?

1 Ответ

4 голосов
/ 01 февраля 2020

Компиляторы часто предпочитают if-преобразование в cmov, когда обе стороны ветви короткие, особенно с троичным, поэтому вы всегда назначаете переменную C. Например, if(x) y=bar; иногда не оптимизируется под CMOV, но y = x ? bar : y; чаще использует CMOV. Особенно, когда y является записью массива, которая в противном случае не была бы затронута: введение неатоми c RMW могло бы создать гонку данных, отсутствующую в источнике. (Компиляторы не могут придумывать записи для объектов с общим доступом.)

Очевидный пример того, когда преобразование if было бы законным, но явно не выгодным, было бы, когда по обе стороны от if / было выполнено много работы. остальное. например, некоторые умножают и делят, целые l oop и / или таблицы поиска. Даже если g cc может доказать, что безопасно запускать обе стороны и выбирать один результат в конце, он увидит, что выполнение этой гораздо большей работы не стоит избегать ветвления.

If-преобразование в зависимость от данных (без ветвления cmov) возможна только в ограниченных случаях. Например, Почему g cc разрешено спекулятивно загружать из структуры? показывает случай, когда это можно / нельзя сделать. Другие случаи включают в себя доступ к памяти, которого нет у абстрактной машины C, что компилятор не может доказать, что это не будет ошибкой. Или не встроенный вызов функции, который может иметь побочные эффекты.

См. Также эти вопросы о получении g cc для использования CMOV.

См. Также Отключение предикации в gcc / g ++ - очевидно, gcc -fno-if-conversion -fno-if-conversion2 отключит использование cmov.

Для случая, когда cmov ухудшает производительность, см. g cc флаг оптимизации -O3 делает код медленнее, чем -O2 - G CC -O3 нуждается в оптимизации на основе профиля, чтобы получить правильную и использовать ветвь для if, который оказывается весьма предсказуемым. G CC -O2 не выполнял преобразование if, даже без данных профилирования P GO.

Другой пример: Есть ли веская причина, по которой G CC будет генерировать прыжок, чтобы перепрыгнуть только через одну дешевую инструкцию?

G CC s изрядно пропускает простую оптимизацию показывает случай, когда троичный имеет побочные эффекты в обеих половинах: троичный не похож на CMOV: только одна сторона даже оценивается для побочных эффектов.

AVX-512 и Ветвление показывает пример на Фортране, где G CC нужна помощь от изменений источника, чтобы иметь возможность использовать SIMD без ответвлений. (Эквивалент скалярного CMOV). Это случай не изобретать записи: он не может превратить чтение / ветвь в чтение / возможно-изменение / запись для элементов, которые источник не написал бы. Если для векторизации обычно требуется преобразование if.

...