Значение 2 является очень особенным значением. Если компилятор знает, что он всегда делится на 2, он может просто сдвинуть биты вместо выполнения арифметических вычислений. Однако в progb
компилятор должен считать с любым возможным целочисленным значением, поэтому должен реализовывать реальное деление, а не просто сдвиг битов.
Таким образом, доступ к аргументу не препятствует какой-либо оптимизации. Использование фиксированного значения позволяет провести некоторую конкретную оптимизацию. Особенно, если это степень 2.
Проверьте разницу на https://godbolt.org/z/TcJxYK
Общая версия использует
idiv ecx
версия, деленная на 2 использует
shr edx, 31
add eax, edx
sar eax
Инструкция idiv
намного медленнее, чем сдвиги и сложения.
Для не степеней двойки она все еще оптимизируема, но, как правило, также включает в себя арифметические операции в виде умножений, сложений и вычитанийне просто сдвиги. Тем не менее, они быстрее, чем деление. Деление - очень медленная операция.
Как указал Стив, использование -fwhole-program
позволяет компилятору компилировать все модули вместе, а также может предполагать, что ему не нужно генерировать ненужные подпрограммы.
Кстати, для упрощенных подпрограмм, которые я использовал в ссылке Godbolt выше, gfortran оптимизирует вызов подпрограммы даже без -fwhole-program
.