Влияние на производительность при наличии нескольких возвратов - PullRequest
1 голос
/ 10 апреля 2020

Взгляните на приведенный ниже сценарий.

;some code 
 test reg1,reg2
je jump1
 ;do something
 add rsp,20
 pop rdx
 ret
jump1:
 ;do something
 cmp reg2,reg3
 jg jump2
 add rsp,20
 pop rdx
 ret
jump2:
 ;do something
 add rsp,20
 pop rdx
 ret

Подобные сборки обычно не встречаются в разобранных кодах. Возможно, компиляторы справляются с этим очень эффективно.

Может ли несколько операторов return повлиять на производительность? Каковы возможные результаты производительности при использовании одного возврата с jmp по сравнению с вышеупомянутым?

1 Ответ

3 голосов
/ 10 апреля 2020

Это называется оптимизацией "дублирования хвоста". Некоторые компиляторы делают это иногда. например, Сообщение в блоге LLVM об этом

Обычно хорошо, когда эпилоги вашей функции маленькие (всего 1 поп), поэтому они не стоят дорого, особенно на современных x86 с большими кешами и хорошая плотность кода (ret и pop являются однобайтовыми). Хотя, если ожидается, что только один путь через функцию будет «горячим», возможно, лучше использовать другой jmp для горячего, чтобы сэкономить небольшое количество пространства UOP-кэша.

Это экономит один занятый jmp на этом пути из функции. Влияние на производительность зависит от окружающего кода, как всегда для глубоко конвейерного суперскалярного неупорядоченного ЦП!

Если несколько путей через функцию могут быть горячими в зависимости от того, как используется ваша функция, они могут оба / все будут полностью эффективными.


Вы также можете сделать это для циклов, у которых есть ветвь внутри l oop: продублируйте dec/jcc или что-либо в нижней части l oop вместо того, чтобы прыгать на общий dec/jcc. (Не забудьте обработать проходной путь в обоих / всех случаях!)

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