2014-10-02 5 views
13

Я смущен, где следует использовать инструкции cmov и где использовать jump инструкции по сборке?разница между условными инструкциями (cmov) и инструкциями по прыжкам

С производительности точки зрения:

  • Какая разница в них обоих?
  • Какой из них лучше?

Если возможно, объясните их разницу на примере.

+4

Какой процессор/семейство вы спрашиваете, добавьте соответствующий тег, пожалуйста. –

ответ

15

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. В соответствии с этим условием он имеет зависимость от флагов и другие входные зависимости.)

+0

Также полезно отметить, что предсказанный прыжок в основном свободен, в то время как у movcc небольшая фиксированная стоимость. Прогнозируемый прыжок всегда будет быстрее. (на текущих процессорах x86) –

+1

@Cory: я не вижу основополагающей причины, по которой movcc нельзя просто игнорировать до тех пор, пока бит cc не будет действителен или не будет использоваться нисходящий регистр. Нынешние процессоры этого не делают? Время декодирования команды в основном равно нулю из-за того, что это происходит раньше исполнения. –

+1

Думаю, я должен был сказать «равный или быстрый» - предсказанный прыжок всегда свободен, «movcc» может быть или не быть. «movcc» не прогнозируется, он рассматривается как «добавление» в основном - он вводит зависимость и может быть переупорядочен и может иметь скрытую «задержку» ILP. –