Строка XOR EAX, EAX присваивает начальное значение переменной Result в 0 и может быть перемещена на несколько строк ниже в место, где EAX будет использован в первый раз. Зато она никогда не должна быть помещена в тело цикла, что изменит логику функции, но может быть перед loopStart. Это убирает необходимость в копировании EAX в EDI и обратно в EAX в строке перед строкой комментария //FOR I := START TO STOP DO.
Code: |
function ForLoopBASM12(Start, Stop : Integer) : Integer; asm push ebx push esi push edi mov esi,eax //for I := Start to Stop do mov ecx, esi //Result := 0; xor eax,eax //mov edi,eax //mov eax, edi //begin @LoopStart : cmp ecx, edx ja @LoopEnd //Result := Result + I; add eax,ecx inc ecx //end; jmp @LoopStart @LoopEnd : pop edi pop esi pop ebx end; |
После всего этого мы видим две строки MOV, которые копируют EAX в ECX через ESI. Это оставляет копию EAX в ESI, которая не используется. Поэтому одна пересылка EAX directly into ECX может заменить эти две строки. Это также уменьшение копирования и удаление мертвого кода.
Code: |
function ForLoopBASM13(Start, Stop : Integer) : Integer; asm push ebx //push esi push edi //mov esi,eax //for I := Start to Stop do //mov ecx, esi mov ecx, eax //Result := 0; xor eax,eax //begin @LoopStart : cmp ecx, edx ja @LoopEnd //Result := Result + I; add eax,ecx inc ecx //end; jmp @LoopStart @LoopEnd : pop edi //pop esi pop ebx end; |
После удаления использования ESI, теперь нет необходимости в его сохранении и восстановлении.
Code: |
function ForLoopBASM14(Start, Stop : Integer) : Integer; asm //push ebx //push edi //for I := Start to Stop do mov ecx, eax //Result := 0; xor eax,eax //begin @LoopStart : cmp ecx, edx ja @LoopEnd //Result := Result + I; add eax,ecx inc ecx //end; jmp @LoopStart @LoopEnd : //pop edi //pop ebx end; |
Также, хоть и немного поздно мы видим, что EBX и EDI нигде не используются. После их удаления и удаления комментариев, в результате получилась следующая красивая функция.
Code: |
function ForLoopBASM15(Start, Stop : Integer) : Integer; asm mov ecx, eax //Result := 0; xor eax,eax //for I := Start to Stop do @LoopStart : cmp ecx, edx ja @LoopEnd //Result := Result + I; add eax,ecx inc ecx jmp @LoopStart @LoopEnd : end; |
Это потребовало много времени и усилий по оптимизации, поскольку мы начали с не оптимизированной версии компилятора. Данный длинный процесс послужил для иллюстрации количества работы оставленной компилятором для оптимизации. Иногда мы не используем должные алгоритмы для оптимизации, но мы можем получить тот же самый результат, используя их.
Вместо проведения такого длинного пути над функцией мы можем позволить откомпилировать Паскаль функцию с включенной оптимизацией. Компилятор должен сделать всю оптимизацию, которую сделали мы.
Code: |
function ForLoopOpt(Start, Stop : Integer) : Integer; var I : Integer;
begin { } Result := 0; { xor ecx,ecx } for I := Start to Stop do { sub edx,eax jl +$08 inc edx xchg eax,edx } begin Result := Result + I; { add ecx,edx inc edx } end; { dec eax jnz -$06 } { mov eax,ecx } end; |
В данном случае Delphi действительно сделало прекрасную работу. Только две строки режут наши глаза. XCHG EAX, EDX простой обмен значениями в EAX и EDX, и MOV EAX, ECX копирует результат в EAX. Обе строки находятся за пределами цикла и не отнимают много времени. Теперь мы имеем две функции – одна без оптимизации цикла и одна с двумя. Для полного комплекта нам нужно еще две функции, одна с обратным циклом и одна с переменной NoName, только с оптимизацией. В начале урока мы видели, как удалить две оптимизации и это я сделал в двух оставшихся функциях. В Delphi оптимизированной выше функции, я оптимизировал инструкцию XCHG для обмена значений двух регистров.
Поскольку мы хотим увидеть максимальный эффект только от оптимизации циклов, я удалил тело цикла Result := Result + I;
Здесь четыре последние функции.
Code: |
function ForLoopNoLoopInverNoNoName(Start, Stop : Integer) : Integer; asm mov ecx, eax //Result := 0; xor eax,eax //for I := Start to Stop do @LoopStart : cmp ecx, edx ja @LoopEnd inc ecx jmp @LoopStart @LoopEnd : end; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!