Подтвердить что ты не робот

Разница между условными инструкциями (cmov) и инструкциями перехода

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

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

  • В чем разница между ними?
  • Какой из них лучше?

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

4b9b3361

Ответ 1

movcc - это так называемая предикатная инструкция. Эта фантазия говорит о том, что "эта инструкция выполняется при условии (предикат)".

Многие процессоры, включая x86, после выполнения арифметической операции (особенно сравнения инструкций), устанавливают биты кода условия, чтобы указать статус результата операции.

Команда условного перехода проверяет биты кода состояния для состояния и, если true, переходит к назначенной цели.

Поскольку скачок является условным, и процессор, как правило, имеет глубокий конвейер, биты кода состояния могут быть буквально не готовы для команды jmp для обработки, когда ЦП встречает команду jmp. Разработчики чипов могли просто подождать, пока трубопровод будет стекать (часто много тактов), а затем выполнить jmp, но это сделает процессор медленным.

Вместо этого большинство из них предпочитают иметь алгоритм предсказания ветвления, который предсказывает, каким путем будет проходить условный переход. Затем процессор может извлекать, декодировать и выполнять предсказанную ветку (или нет) и продолжать быстрое выполнение, при условии, что если биты кода состояния, которые, наконец, прибывают, оказываются неправильными для условного (ветвь неверного прогноза), процессор отменяет все они работают после ветки и повторно запускают программу, идущую по другому пути.

Условные переходы сложнее для конвейерного выполнения, чем обычные зависимости данных, потому что они могут изменить, какая команда должна быть следующей в потоке инструкций, проходящих через конвейер. Это называется зависимость управления, в отличие от зависимости данных (например, add, где оба входа являются выходами других последних инструкций).

Прогнозы ветки оказываются очень хорошими, потому что большинство отраслей, как правило, имеют предвзятость относительно своего направления. (Филиал в конце большинства циклов, как правило, относится к верху, как правило). Поэтому большую часть времени процессор не должен отказываться от ошибочно предсказанной работы.

Если направление ветки очень непредсказуемо, тогда процессор будет считать неправильным около 50% времени, поэтому придется отменить работу. Это дорого.

ОК, теперь часто находит такой код:

  cmp   ...
  jcc   $
  mov   register1, register2
$: ; continue here
  ...
  ; use register1

Если предсказатель ветвления догадывается правильно, этот код выполняется быстро, независимо от того, в каком направлении идет ветка. Если он догадывается не так много... ох.

Таким образом, инструкция условного перемещения. Это шаг, который условно перемещает данные, основываясь на битах кода условия. Мы можем переписать выше:

  cmp   ...
  movcc  register1, register2
$: ; continue here
  ...
  ; use register1

Теперь у нас нет инструкций о разветвлении, и, следовательно, никаких неверных прогнозов, которые заставляют процессор отменять всю работу. Поскольку нет никакой зависимости от управления, следующие команды должны быть извлечены и декодированы независимо от того, действует ли movcc как mov или nop. Конвейер может оставаться полным, не предсказывая условия и спекулятивно выполняя инструкции, которые используют register1. (Вы могли бы построить CPU таким образом, но это превзошло бы цель movcc.)

movcc преобразует зависимость управления в зависимость данных. Процессор обрабатывает его точно так же, как математическая инструкция с 3 входами, причем входы являются EFLAGS и двумя "обычными" входами (регистр dest и регистр источника или память). На x86, adc идентичен cmovae (mov if CF==0), насколько способ выполнения вне очереди отслеживает зависимости: входы CF и оба регистра GP. Выходом является регистр назначения.

Для x86 существуют cmovcc, jcc и setcc инструкции для каждой комбинации условий cc. (setcc задает адресату 0 или 1. В соответствии с этим условием он имеет зависимость данных от флагов и других входных зависимостей.)