Я заметил, что если мы знаем, что есть хороший шанс того, что поток управления будет истинным или ложным, мы можем сообщить об этом компилятору, например, в ядре Linux, есть много likely
unlikely
, фактически подразумеваемых __builtin_expect
предоставлено gcc
, поэтому я хочу выяснить, как оно работает, затем проверил сборку там:
20:branch_prediction_victim.cpp **** if (array_aka[j] >= 128)
184 .loc 3 20 0 is_stmt 1
185 00f1 488B85D0 movq -131120(%rbp), %rax
185 FFFDFF
186 00f8 8B8485F0 movl -131088(%rbp,%rax,4), %eax
186 FFFDFF
187 00ff 83F87F cmpl $127, %eax
188 0102 7E17 jle .L13
Затем для __builtin_expect
20:branch_prediction_victim.cpp **** if (__builtin_expect((array_aka[j] >= 128), 1))
184 .loc 3 20 0 is_stmt 1
185 00f1 488B85D0 movq -131120(%rbp), %rax
185 FFFDFF
186 00f8 8B8485F0 movl -131088(%rbp,%rax,4), %eax
186 FFFDFF
187 00ff 83F87F cmpl $127, %eax
188 0102 0F9FC0 setg %al
189 0105 0FB6C0 movzbl %al, %eax
190 0108 4885C0 testq %rax, %rax
191 010b 7417 je .L13
- 188 -
setg
установить, если больше, здесь установить, если больше чем? - 189 -
movzbl
переместить ноль, продлить байт в длину, я знаю, что это одно движение %al
в %eax
- 190 -
testq
поразрядно ИЛИ затем установить флаги ZF CF, это правильно?
Я хочу знать, как они влияют на предсказание ветвления и улучшить производительность, три дополнительные инструкции, нужно больше циклов, верно?