🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.asm
Article #253

Re: optymalizacja

#253
From: Bogdan (bogdro)
Date: Thu, 18 May 2006 08:33
140 lines
5927 bytes
tosamo napisał(a):
> Użytkownik "Bogdan (bogdro)" <bogdan@bogdan.pl> napisał w wiadomości 
> news:e4ffrk$he5$1@nemesis.news.tpi.pl...
>> tosamo napisał(a):
>>> Witam
>>>
>>> Pisze sobie porgramik w masm32 (wersja 6.11 chyba). Do tej pory pisalem
>>> glownie w c i pascalu wiec na poczatku
>>> program w asm wygladal jak dokladna kalka z jezykow wyzszego rzedu i 
>>> dzialal
>>> jakies 3 razy wolniej niz
>>> pascal i delphi. Potem zaczalem optymalizowac i wyszlo na to, ze kazda
>>> optymalizacja zwalnia dzialanie programu
>>> o kilka(dziesiat) %.
>> Optymalizacja numer 3: jeśli obie powyższe dają niewystarczające
>> wyniki, sięgaj po assemblera.
> 
> To ma byc na zaliczenie z jezykow asemblerowych wiec musi byc w asm.
> Ciekawe co powie wykladowca jak zobaczy ze w asm wyszlo 5 razy wolniej niz w 
> c
> i 4 razy wolniej niz w delphi.

 A, z tym zaliczeniem to inna mowa teraz. Czasem może być ciężko pobić
kompilator. Popatrz na moje wskazówki pod koniec, może coś się uda.

>> Należy rozdzielać instrukcje zależne.
> 
> Ale o co chodzi ?

 Jak masz takie coś:

	mov	eax, [zmienna]
	add	eax, 2
	mov	ebx, [zmienna2]
	add	ebx, 10
	mov	ecx, [zmienna3]
	sub	ecx, 20

to lepiej powinno wyjść:

	mov	eax, [zmienna]
	mov	ebx, [zmienna2]
	mov	ecx, [zmienna3]
	add	eax, 2
	add	ebx, 10
	sub	ecx, 20

Chodzi o to, że jeśli instrukcje operujące na tym samym rejestrze nie
muszą być obok siebie, to niech nie będą.

> 
>>>  {..}
>>>     lodsd
>> Instrukcje łańcuchowe są powolne.
> 
> A ja caly czas zylem w przeswiadczeniu, ze to najszybszy sposob na 
> kopiowanie
> pamieci. W takim razie co bedzie szybsze ?
> 
> Takie cos ?
> 
> mov eax,dword ptr [esi]
> inc esi

 Czasem tak, choć nie mierzyłem. Jakby się jeszcze udało oddzielić te
dwie instrukcjami niezależnymi od ESI, to powinno być jeszcze lepiej.
Najnowsze procesory nawet bardziej lubią "add esi, 1" niż "inc esi".

 Najlepiej moim zdaniem używać złożonych sposobów adresowania (np.
takich, jakie podałeś w pierwszym fragmencie kodu: [edi-xxx]), a potem
podbijać rejestr wskazujący (tu: ESI) o większą liczbę na raz, jeśli
możliwe.

> Ja nie probuje lamac sha. Musze tylko zrobic zeby bylo chociaz o kilka % 
> szybsze niz
> przyklad w c i bedzie ok. Juz mi wyszlo, ze dla duzych blokow danych jest 
> szybszy tylko
> z malymi sobie nie radzi.

 Bo to tak jest z instrukcjami łańcuchowymi: lods*, movs*, ...
Zaczynają one sobie radzić dopiero przy większych porcjach danych.
Kiedyś widziałem testy, że dla małych porcji danych najszybciej
wychodzi "ręczne" kopiowanie (mov itp), dla średnich (powiedzmy,
64-512 bajtów) - rep movs*, dla dużych - MMX i SSE. Mimo iż to było z
REP, to same instrukcje też nie są genialnie szybkie (4 cykle, w
porównaniu do 0.5 czy 1 niektórych MOV). Po prostu są one dość złożone.

 Jeszcze kilka rad dorzucę:

- często używane zmienne załaduj do rejestrów. Czasem tych cząstkowych
trzeba będzie używać, ale może jednak coś przyspieszy.

- stosując CMOVcc, SETcc wyeliminuj tyle skoków warunkowych, ile się
tylko da.

- po każdym JMP daj UD2, co zahamuje niepotrzebne dekodowanie dalszych
instrukcji

- istotne etykiety (może nawet wszystkie) ułóż dyrektywą "align 16" na
adresach podzielnych przez 16. W ten sposób małe fragmenty kodu między
dwoma etykietami (lub czasem całe procedury) nie będą przełamane na
zbyt dużo linii pamięci podręcznej cache procesora. Przykład:

align 16
funkcja:
	...

Jeśli funkcja na pewno już się nie zmieni, to rozważ, czy nie lepiej
wkleić ją w miejsce CALL, bo uruchamianie funkcji i powrót też swoje
trwają.

- dane układaj według malejących rozmiarów, przed pierwszą z nich daj
"align 16", głównie z tych samych powodów co wyżej.

- jeśli jakieś instrukcje zależne muszą być blisko siebie, spróbuj
rozdzielić kilkoma NOPami. Czasem pomaga.

- unikaj mnożenia MUL przez małą stałą liczbę (ostatnio mul
przyspieszył, więc mnożenie już tak nie boli jak dawniej).

- jeśli procesor to Pentium IV lub okolice, unikaj SHL i stosuj ADD
zamiast niego

- zamiast "or rej1, rej1", używaj "test rej1, rej1" (na tym samym
rejestrze)

- w ostatecznej wersji programu nie może być żadnego wyświetlania w
pętlach (chyba że absolutnie naprawdę konieczne). Wyświetlanie nieźle
zamula.

- zamiast kilku PUSHów na rejestrach, daj "sub esp, xxx" i sekwencję
"mov [esp+xxx], yyy". Jeśli możliwe, przekazuj parametry (o ile są
potrzebne) w rejestrach. Dla twardzieli: nie używaj EBP w funkcjach i
operuj na ESP.

-- 
Pozdrawiam, Bogdan                                  (Linux i FreeDOS)
Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
Prawdziwy, bezpieczny komunikator:                   www.JabberPL.org
Technical Details
Message-ID: <e4hbi4$fpm$1@atlantis.news.tpi.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.nask.pl!news.nask.org.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail
References: <e4f5nl$rj4$1@inews.gazeta.pl> <e4ffrk$he5$1@nemesis.news.tpi.pl> <e4fi7h$q1b$1@inews.gazeta.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.nask.pl!news.nask.org.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail
From: "Bogdan (bogdro)" <bogdan@bogdan.pl>
Newsgroups: pl.comp.lang.asm
Subject: Re: optymalizacja
Date: Thu, 18 May 2006 10:33:45 +0200
Organization: tp.internet - http://www.tpi.pl/
Lines: 140
Message-ID: <e4hbi4$fpm$1@atlantis.news.tpi.pl>
References: <e4f5nl$rj4$1@inews.gazeta.pl> <e4ffrk$he5$1@nemesis.news.tpi.pl> <e4fi7h$q1b$1@inews.gazeta.pl>
NNTP-Posting-Host: acrj19.neoplus.adsl.tpnet.pl
Mime-Version: 1.0
X-Trace: atlantis.news.tpi.pl 1147941252 16182 83.11.11.19 (18 May 2006 08:34:12 GMT)
X-Complaints-To: usenet@tpi.pl
NNTP-Posting-Date: Thu, 18 May 2006 08:34:12 +0000 (UTC)
User-Agent: Thunderbird 1.5.0.2 (X11/20060420)
In-Reply-To: <e4fi7h$q1b$1@inews.gazeta.pl>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit