Они оба декодируют с одинаковым количеством внутренних мопов, но место назначения памяти add
получает эти мопы через внешний интерфейс за меньшее количество мопов с объединенными доменами на современных процессорах Intel / AMD.
В процессорах Intel add [mem], imm
декодирует в микросреду с нагрузкой + добавлением и с микросинтеграцией в адресе хранилища + в хранилище данных, так что всего 2 мопа слитых доменов для внешнего интерфейса. Процессоры AMD всегда хранят операнды памяти, сгруппированные с операцией ALU, не называя это «микро-слиянием», это просто, как они всегда работали. (https://agner.org/optimize/ и IN C инструкция против ADD 1: это имеет значение? ).
Первый способ не оставьте значение в регистре , чтобы вы не могли использовать его как часть ++a
, если использовалось значение выражения. Только для побочного эффекта на память.
Использование [rbp - 4]
и увеличение локального в памяти пахнет как неоптимизированный код / режим отладки, который вы не должны обратите внимание на то, что эффективно. Оптимизированный код обычно использует [rsp +- constant]
для обращения к местным жителям, и (если переменная не volatile
) не будет просто сразу сохранять его обратно в память.
Почему clang создает неэффективный asm с -O0 (для этой простой суммы с плавающей запятой)? - компиляция в режиме отладки, иначе -O0
(по умолчанию) компилирует каждый оператор C отдельно, и обрабатывает каждую переменную вроде volatile
, что совершенно ужасно.
См. Как удалить "шум" из вывода сборки GCC / clang? о том, как получить компиляторы чтобы сделать asm интересным. Напишите функцию, которая принимает аргументы и возвращает значение, чтобы она могла что-то делать без оптимизации или распространения констант в mov eax, constant_result
.