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

FLD DSIZE PTR [DA]
FLD DSIZE PTR [ESI+DSIZE*ECX]
FMUL ST,ST(1)
FLD DSIZE PTR [ESI+DSIZE*ECX+DSIZE]
FMUL ST,ST(2)
FLD DSIZE PTR [ESI+DSIZE*ECX+2*DSIZE]
FMUL ST,ST(3)
FXCH ST(2)
FSUBR DSIZE PTR [EDI+DSIZE*ECX]
FXCH ST(3)
FMUL DSIZE PTR [ESI+DSIZE*ECX+3*DSIZE]
FXCH
FSUBR DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
FXCH ST(2)
FSUBR DSIZE PTR [EDI+DSIZE*ECX+2*DSIZE]
FXCH
FSUBR DSIZE PTR [EDI+DSIZE*ECX+3*DSIZE]
FXCH ST(3)
FSTP DSIZE PTR [EDI+DSIZE*ECX]
FSTP DSIZE PTR [EDI+DSIZE*ECX+2*DSIZE]
FSTP DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
FSTP DSIZE PTR [EDI+DSIZE*ECX+3*DSIZE]
ADD ECX, 4 ; увеличиваем индекс на 4
JNZ L3 ; цикл
L4:

Обычно, легче всего найти решение без потерь тактов - это использовать
развертывание в 4 раза, т.к. в этом случае нет необходимости в свертывании.
Число дополнительных операций, за пределами основного цикла - остаток от
деления N на 4 расчитываются легко, без деления. Дополнительные операции
сделаны перед основным циклом, а не после, что бы сделать обработку счетчика
цикла более простым.

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

В качестве общей рекомендации, я пожалуй скажу, что если N велико или если
без развертывания вы не можете удалить достаточное количество потерь тактов,
то вам следует развернуть цикл с целочисленными операциями в 2 раза, а цикл
с плавающей точкой в 4.

17. ОБЗОР СПЕЦИАЛЬНЫХ ИНСТРУКЦИЙ
================================

17.1 LEA
--------
Инструкция LEA используется для многих целей, поскольку она может делать
сдвиг, сложение/вычитание, и загрузку помимо этого она спариваемая и
исполняется за один такт. Например: