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

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

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

Эпилог кода делает 1-3 операции, могут быть организованны как отдельный цикл,
но это дополнительная нагрузка на механизм предсказания переходов, так что
приведенное выше решение - самое быстрое.

А теперь, когда я испугал вас сложностью развертывания в 3 раза, я
продемонстрирую вам более легкое развертывание в 4 раза:

Пример 13:

DSIZE = 8 ; размер данных
MOV EAX, [N] ; количество элементов
MOV ESI, [X] ; указатель на X
MOV EDI, [Y] ; указатель на Y
XOR ECX, ECX
LEA ESI, [ESI+DSIZE*EAX] ; указатель на конец X
SUB ECX, EAX ; -N
LEA EDI, [EDI+DSIZE*EAX] ; указатель на конец Y
TEST AL,1 ; тест N на нечетность
JZ SHORT L1
FLD DSIZE PTR [DA] ; делаем нечетную операцию
FMUL DSIZE PTR [ESI+DSIZE*ECX]
FSUBR DSIZE PTR [EDI+DSIZE*ECX]
INC ECX ; коррекция счетчика
FSTP DSIZE PTR [EDI+DSIZE*ECX-DSIZE]
L1: TEST AL,2 ; тест возможности более 2 операций
JZ L2
FLD DSIZE PTR [DA] ; N MOD 4 = 2 или 3. Делаем еще две
FMUL DSIZE PTR [ESI+DSIZE*ECX]
FLD DSIZE PTR [DA]
FMUL DSIZE PTR [ESI+DSIZE*ECX+DSIZE]
FXCH
FSUBR DSIZE PTR [EDI+DSIZE*ECX]
FXCH
FSUBR DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
FXCH
FSTP DSIZE PTR [EDI+DSIZE*ECX]
FSTP DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
ADD ECX, 2 ; счетчик теперь делим на 4
L2: TEST ECX, ECX
JZ L4 ; нет больше операций
L3: ; main loop: