В AMD, Intel Broadwell и более поздних версиях CMOV составляет всего 1 моп, с 1 циклом задержки.Или 2 uops / 2 цикла на Haswell и ранее.Это ваша лучшая ставка для условного обнуления регистра.
xor r10d, r10d # r10=0. hoist out of loops if possible
test al, 1 # test the low bit of RAX, setting ZF
cmovz rax, r10 # zero RAX if the low bit was zero, otherwise unmodified
(кодировка test r64, imm8
не существует, поэтому вы хотите использовать регистр с низким значением 8, если вы тестируете маску с нулевым значением снаружи).младшие 8 бит.)
Если битовая позиция находится в регистре, bt reg, reg
только 1 моп на Intel и AMD.(bts reg,reg
равно 2 моп на AMD K8 через Ryzen, но обычный bt
, который устанавливает CF в соответствии со значением выбранного бита, дешев на AMD и Intel.)
bt rax, rdx # CF = RAX & (1<<rdx)
cmovnc rax, r10
С обоими этимипроверяемый регистр может отличаться от пункта назначения CMOV.
См. https://agner.org/optimize/ для получения дополнительной информации о производительности, а также https://stackoverflow.com/tags/x86/info