Содержание материала

 

Строка 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;

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить