movcc является так называемым Предполагаемая инструкция. Это причудливо - говорят, что «эта инструкция выполняется при условии (предикат)».
Многие процессоры, включая x86, после выполнения арифметической операции (особенно сравнения инструкций), устанавливают биты кода условия, чтобы указать статус результата операции.
Инструкция условного перехода проверяет биты кода состояния для статуса и, если значение true, переходит к назначенной цели.
Поскольку переход является условным, и процессор обычно имеет глубокий конвейер, биты кода состояния могут быть буквально не готовы для команды jmp для обработки, когда CPU встречает инструкцию jmp. Разработчики чипов могли просто ждать, пока трубопровод будет стекать (часто много тактов), а затем выполнить jmp, но это сделает процессор медленным.
Вместо этого, большинство из них предпочитает иметь предсказание ветви алгоритм, который предсказывает, в каком направлении будет проходить условный переход. Затем процессор может извлекать, декодировать и исполнять предсказанную ветку (или нет) и продолжать быстрое выполнение, при условии, что если бит кода состояния, который, наконец, прибывает, окажется неправильным для условного (branch mispredict), процессор отменяет всю работу, выполняемую после ветки, и повторно выполняет программу, идущую по другому пути.
Условные переходы сложнее для конвейерного выполнения, чем обычные зависимости данных, поскольку они могут изменять, какая команда должна быть следующей в потоке инструкций, протекающих по конвейеру. Это называется control dependency, в отличие от зависимости от данных (например, add
, где оба входа являются выходами других последних инструкций).
Прогнозы ветви окажутся очень хорошими, потому что большинство ветвей имеют тенденцию иметь предвзятость относительно их направления. (Филиал в конце большинства циклов, как правило, относится к верху, как правило). Поэтому большую часть времени процессор не должен отказываться от ошибочно предсказанной работы.
Если направление ветви очень непредсказуемо, то процессор догадается неправильно около 50% времени, поэтому придется отменить работу. Это дорого.
ОК, теперь, один часто находит такой код:
cmp ...
jcc $
mov register1, register2
$: ; continue here
...
; use register1
Если ветвь предсказатель угадывает правильно, этот код не очень быстро, независимо от того, каким образом отрасль идет. Если он догадывается не так много ... ох.
Таким образом, условное перемещение инструкция. Это шаг, который условно перемещает данные, основываясь на битах кода условия. Мы можем переписать выше:
cmp ...
movcc register1, register2
$: ; continue here
...
; use register1
Теперь у нас нет инструкции ветвления, и, следовательно, не mispredicts, которые делают процессор отменить все работу. Поскольку нет управляющей зависимости, следующие команды должны быть извлечены и декодированы независимо от того, действует ли movcc
как mov
или nop
. Трубопровод может оставаться полным, не предсказывая условия и спекулятивно выполняя инструкции, которые используют register1
. (Вы могли бы построить CPU таким образом, но это победит цель movcc
.)
movcc
преобразует зависимость управления в зависимость данных. Процессор обрабатывает его точно так же, как математическая инструкция с 3 входами, причем входы являются EFLAGS и двумя «обычными» входами (регистр dest и регистр источника или память). На x86 adc
идентичен cmovae
(mov, если CF==0
), насколько способ выполнения вне очереди отслеживает зависимости: входы CF и оба регистра GP. Вывод - регистр назначения.
Для x86 есть cmovcc
, jcc
и setcc
инструкции для каждой комбинации условий cc. (setcc
задает пункт назначения 0 или 1. В соответствии с этим условием он имеет зависимость от флагов и другие входные зависимости.)
Какой процессор/семейство вы спрашиваете, добавьте соответствующий тег, пожалуйста. –