Для записи, gcc, при компиляции с специально отключенной оптимизацией (-O0
), выдает различный код для двух входов (в моем случае тело foo
было return rand();
, так что результат не был бы определяется во время компиляции).
Без временной переменной t
:
movl $0, %eax
call foo
testl %eax, %eax
je .L4
/* inside of if block */
.L4:
/* rest of main() */
Здесь возвращаемое значение foo
сохраняется в регистре EAX, и регистр проверяется на самом себе, чтобы определить, равен ли он 0, и если да, то он перепрыгивает через тело блока if.
С временной переменной t
:
movl $0, %eax
call foo
movl %eax, -4(%rbp)
cmpl $0, -4(%rbp)
je .L4
/* inside of if block */
.L4:
/* rest of main() */
Здесь возвращаемое значение foo
сохраняется в регистре EAX, а затем помещается в стек. Затем содержимое местоположения в стеке сравнивается с литералом 0, и если они равны, оно перепрыгивает через тело блока if.
И поэтому, если мы далее предположим, что процессор не выполняет каких-либо «оптимизаций», когда он генерирует для этого микрокод, то версия без временной должна быть на несколько тактов быстрее. Это не будет существенно быстрее, потому что, хотя версия с временным использованием проталкивания стека, значение стека почти наверняка будет в кеше L1 процессора, когда инструкция сравнения выполняется сразу после слов, и поэтому не будет быть в оба конца в оперативной памяти.
Конечно, код становится идентичным, как только вы включаете любой уровень оптимизации, даже -O1
, и кто скомпилирует все, что настолько критично, что им небезразлично несколько тактов при всех отключенных оптимизациях?
Редактировать: Что касается вашей дополнительной информации о вашем друге аппаратного инженера, я не могу понять, как доступ к значению в кэше L1 будет когда-либо на быстрее , чем доступ к реестру непосредственно. Я мог бы видеть, что он будет примерно таким же быстрым , если значение никогда не покидает конвейер, но я не могу видеть, что он быстрее , тем более что он все еще должен выполнять movl
Инструкция в дополнение к сравнению. Но покажите ему код сборки выше и спросите, что он думает; это будет более продуктивно, чем пытаться обсудить проблему с точки зрения C.