2013-08-12 2 views
4

В классах программирования нашей системы мы изучаем язык ассемблера. В большинстве примеров программ наш проф. показал в классах; он использует:Есть ли преимущества в следующих командах сборки?

XOR CX, CX 

вместо

MOV CX, 0 

или

OR AX, AX 
JNE SOME_LABEL 

вместо

CMP AX, 0 
JNE SOME_LABEL 

или

AND AL, 0FH  ; To convert input ASCII value to numeral 
; The value in AL has already been checked to lie b/w '0' and '9' 

вместо

SUB AL, '0' 

Мой вопрос заключается в следующем, есть какой-то более высокой производительности при использовании (легко понять/чтения) метод AND/OR или XOR вместо альтернативного?

Поскольку эти программы, как правило, показаны нам во время лекций по теоретической лекции, большинство классов неспособно фактически оценить их в устной форме. Зачем тратить 40 минут на лекцию, объясняя эти тривиальные заявления?

+4

Инструкции могут быть короче и не содержат нулевых байтов. –

+0

... и существуют специальные оптимизации, такие как переименование регистра, которые распознают «xor eax, eax» –

ответ

6
XOR CX, CX ;0x31 0xC9 

использует только два байта: OPCODE 0x31 и ModR/М байт, который хранит источника и назначения регистр (в данном случае эти две такие же).

MOV CX, 0 ;0xB8 0x08 0x00 0x00 

нуждается в большем количестве байт: опкод 0xB8, ModR/M для назначения (в данном случае CX) и два байта немедленным заполняются нулями. Нет разницы с перспективой синхронизации (оба берут только один такт), но mov нуждается в 4 байтах, а xor использует только два.

OR AX, AX ;0x0A 0xC0 

снова использует только опкод байт и ModRM байт, в то время как

CMP AX, 0 ;0x3D 0x00 0x00 <-- but usually 0x3B ModRM 0x00 0x00 

использует три или четыре байта. В этом случае он использует три байта (код операции 0x3D, слово немедленное представляет ноль), поскольку x86 имеет специальные коды операций для некоторых операций с регистром Accumulator, но обычно он будет использовать четыре байта (код операции, ModR/M, word немедленный). Это опять то же самое, когда речь идет о процессорных часах.

Там нет никакой разницы в процессор при выполнении

AND AL, 0x0F ;0x24 0x0F <-- again special opcode for Accumulator 

и

SUB AL, '0' ;0x2D 0x30 0x00 <-- again special opcode for Accumulator 

(только один разностный байт), но когда вы вычесть ASCII ноль, вы не можете быть уверены, что выиграл» t остается значением больше 9 в аккумуляторе. Также наборы OF и CF равны нулю, тогда как sub устанавливает их в соответствии с результатом AND ing может быть более безопасным, но мое личное мнение состоит в том, что это использование зависит от контекста.

1

Важным отличием является то, влияют ли они на флаги операций ЦП. Когда вы используете логические операции xor, or и т. Д., Тогда действуют флаги операций. Итак:

XOR CX, CX 

не только обнулить CX, но, к примеру, будет установлен нулевой флаг процессора. Инструкция mov не влияет на флаги. Таким образом:

MOV CX, 0 

Не укажет, например, флаг нуля.

+0

Когда ZF необходимо после этого использования «xor»? – user35443

+2

@ user35443, это может потребоваться, если вы проверяете флаги в точке, которая, возможно, была получена из более чем одного места в коде. Таким образом, место, где происходит проверка, может не знать, что инструкция, связанная с предшествующим флагом, была «xor». – lurker

+0

Я этого не заметил, спасибо! – user35443

-1

Операция XOR работает быстрее, чем MOV, поскольку это побитовая операция, все побитовые операции выполняются быстрее CPU.

+0

А? Почему вы используете коммутатор для реализации XOR? – Michael

+0

Я хотел написать побитовое, извините, мое плохое – StrawhatLuffy

+0

Это неправда.Как mov reg, imm, так и xor reg, reg - только один такт. – user35443

3

Помимо экономии размера кода, упомянутой в других ответах, я думал, что я упомяну еще несколько вещей, которые вы можете прочитать больше в Intel's optimization manual и Agner Fog's x86 optimization guide:

XOR REG,REG и SUB REG,REGREG одинаковыми для оба операнда) распознаются современными процессорами x86 как зависимые выключатели; что они также служат цели в нарушении ложных зависимостей от предыдущих значений регистра/флага. Обратите внимание, что это не обязательно применяется, если вы очищаете 8- или 16-разрядный регистр, но это произойдет, если вы очистите 32-разрядный регистр.


OR AX, AX 
JNE SOME_LABEL 

Я считаю, что предпочтительная инструкция будет TEST AX,AX. TEST может быть макроконфигурирован с любым условным прыжком (в основном в сочетании с инструкцией перехода в одну инструкцию перед декодированием) на современных процессорах x86. CMP может соединяться только с неподписанными условными переходами, по крайней мере до архитектуры Nehalem. Опять же, я не уверен, что это так для 16-битных операндов.

+0

'mov' ломает зависимости от предыдущего значения регистра. Он упоминается только для «xor» и т. Д., Потому что в общем случае вывод * * * зависит от предыдущего значения, и поэтому ему нужна специальная поддержка для распознавания этого случая. 'movzx',' movd' и т. д. все ноль остальной части регрессии, и, таким образом, разрывают цепочки разломов. (в отличие от 'pinsrw' или' movlhps'.) –

1

В дополнение к ранее описанному инструкциям, какая инструкция быстрее, также может зависеть от исполняемой последовательности исполняемых команд.

Пример замечательной невинной инструкции, имеющей большое влияние, см. Стр. 8 в this paper от Torbjörn Granlund от славы GMP. В примере три в правом верхнем углу страницы очень быстрый цикл разделения начинается с инструкции «nop». В соответствии с примечанием 4 на той же странице отсутствие инструкции nop заставляет цикл выполнять 1 такт синхронизации медленнее. Гранлунд предлагает экспериментировать, помещая другие петли внутри петли для достижения дальнейших ускорений.

Моя первоначальная реакция на это была больше инструкций = больше времени. Тем не менее, очевидно, что гораздо больше запланированы и выполняются инструкции, чем можно почерпнуть из руководств.

+0

Это, вероятно, лучше подходит для более поздних инструкций для сложных/простых декодеров. Core2 предшествует кешу цикла (Nehalem) и кэш uop (Sandybridge), поэтому пропускная способность декодера была фактором даже для коротких циклов. –

Смежные вопросы