"Оптимизация для PENTIUM процессора" - читать интересную книгу автора

MOV ESI, [A]
MOV EDI, [B]
CLD
L1: LODSD
NEG EAX
STOSD
LOOP L1
L2: POP EDI
POP ESI
RET ; (ни каких других pop если мы используем соглашения C)
_ChangeSign ENDP

Это похоже на хорошее решение, но оно не оптимально, потому что в цикле
используются медленные не спаривающиеся инструкции. Цикл исполниться за
11 тактов, если все данные на уровне L1 кеша.

Используем только спариваемые инструкции
----------------------------------------

Пример 2:

MOV ECX, [N]
MOV ESI, [A]
TEST ECX, ECX
JZ SHORT L2
MOV EDI, [B]
L1: MOV EAX, [ESI] ; u
XOR EBX, EBX ; v (спаривание)
ADD ESI, 4 ; u
SUB EBX, EAX ; v (спаривание)
MOV [EDI], EBX ; u
ADD EDI, 4 ; v (спаривание)
DEC ECX ; u
JNZ L1 ; v (спаривание)
L2:

Здесь мы использовали только спариваемые инструкции, и спланировали цикл так,
что все инструкции спарились. Теперь одна итерация исполняется за 4 такта. Мы
могли бы получить ту же скорость не разбивая инструкцию NEG, но тогда нам
придется разбить другие не спаривающиеся инструкции.

Использование одного регистра для счетчика и индекса
----------------------------------------------------

Пример 3:

MOV ESI, [A]
MOV EDI, [B]
MOV ECX, [N]
XOR EDX, EDX