Вызывает ли `add` в ячейке памяти быстрее, чем вызывает его в регистре, а затем перемещает значение? - PullRequest
2 голосов
/ 23 апреля 2020

Что быстрее:

add DWORD PTR [rbp-0x4],1

или

 mov    eax,DWORD PTR [rbp-0x4]
 add    eax,1
 mov    DWORD PTR [rbp-0x4],eax

Я видел второй код, сгенерированный компилятором, так что, возможно, вызов add в регистре намного быстрее?

Ответы [ 2 ]

5 голосов
/ 23 апреля 2020

Они оба декодируют с одинаковым количеством внутренних мопов, но место назначения памяти 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.

2 голосов
/ 23 апреля 2020

Добавление в регистр, вероятно, происходит на быстрее (поскольку регистры встроены в микросхему), но, поскольку вам все равно придется загружать и хранить данные, вы вряд ли увидите улучшение.

Долгосрочный подход может быть даже медленнее , поскольку у ЦП могут быть возможности оптимизировать более короткий код. Кроме того, более короткий код может иметь атомарность для чтения / изменения / записи, в зависимости от того, как вы его кодируете. Это, безусловно, не приведет к потере регистра eax.

Суть в том, что более длинный код вряд ли будет достаточен для улучшения (если таковое имеется), чтобы оправдать хит читаемости.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...