Ответ 1
При оптимизации для процессоров Intel всегда устанавливайте инструкцию по настройке флага перед инструкцией условного перехода, чтобы они могли вставлять макросы в один уровень в декодерах. Это не значительно хуже для старых процессоров. Вы можете урезать штраф за неверное предсказание ветки на единицу для процессоров, которые не используют пары сравнения и ветвления с использованием макросов. В правильно спрогнозированном случае, один дополнительный op занимает пространство в буфере повторного заказа за один дополнительный цикл. Я не думаю, что любой из них оправдывает разделение инструкций сравнения и ветвления. Я думаю, что более высокая пропускная способность процессора на Intel более значительна.
AMD Bulldozer/Piledriver/Steamroller может слить test/cmp
с любым jcc
, но только test/cmp
, а не с любыми другими инструкциями ALU. Так что определенно положите сравнение с ветвями.
Из руководство Agar Fog's, таблица 9.2 (для Sandybridge/Ivybridge):
First | can pair with these | cannot pair with
instruction | (and the inverse) |
---------------------------------------------
cmp |jz, jc, jb, ja, jl, jg| js, jp, jo
add, sub |jz, jc, jb, ja, jl, jg| js, jp, jo
adc, sbb |none |
inc, dec |jz, jl, jg | jc, jb, ja, js, jp, jo
test | all |
and | all |
or, xor, not, neg | none |
shift, rotate | none |
Table 9.2. Instruction fusion
В принципе, inc/dec
может использовать макро-предохранитель с jcc
, пока условие зависит только от битов, которые были изменены с помощью inc/dec
. (В противном случае они не являются макро-предохранителями, и вы получаете дополнительный uop, вставленный для слияния флагов (например, когда вы читаете eax
после записи al
). Или на более ранних процессорах, срыв частичных флагов.)
Core2/Nehalem был более ограничен в возможности макро-слияния, и Core2 не мог сглаживать макросы в режиме 64 бит.
Чтение Agner Fog, оптимизирующее asm и руководства C, тоже, если вы еще этого не сделали. Они полны необходимых знаний.