••• Assembler pro začátečníky ][ ••• (Proč používáme assembler - základy optimalizace) V první části mojí miniučebnice assembleru, jsem vás seznámil se základy programovaní v assembleru. Ale asi uznáte, že psát všechny programy kompletně v assembleru je velice neefektivní a mnohdy zbytečné. Proto většina z nás využívá vymožeností hi-level jazyků. Chci se proto zaměřit na použití assembleru v hi-level jazycích, tedy hlavně pro low-level optimalizaci programů. Základem efektivního využívaní optimalizace je přibližná představa o tom, jak kompilátor, kterým svůj program kompilujete, generuje výsledný kód. Pokud jste provedli všechny hi-level optimalizace jako odstranění zbytečných volání funkcí ve výkonné smyčce a nahradili časově náročné funkce předpočítanými tabulkami, je na řadě přepsat časově kritická místa do assembleru. Prvním krokem optimalizace je vyloučit zbytečné přístupy do paměti a všechny potřebné konstanty a výpočty provádět pomocí registrů procesoru. Dalším, výrazně urychlujícím krokem je nahrazení časově náročné instrukce jako například mul a div instrukcemi jako shl, shr nebo xchg. Jejich taktování je o proti mul a div až 30x menší. Používají se především v případech, kdy se nějaká proměnná násobí konstantou. Y:=2*X Pascal (8-bit) Assembler (8-bit) mov al,2 {04} mov al,X {08} mov bl,X {08} shl ax,1 {02} mul bl {72} mov Y,ax {09} mov Y,al {09} ------ ----- 93 19 Tímto způsobem se dají velice rychle vynásobit proměnné hodnotami 2^n tedy (2,4,16,32,64,...). Pokud není konstanta mocninou 2, je třeba použít dvou instrukcí. Pro příklad uvedu násobení 320, které se hojně používá v režimu 320x200x256. Y:=320*X Pascal (16-bit) Assembler (16-bit) mov ax,320 {004} mov ax,X {08} mov bx,X {008} xchg al,ah {04} mul bx {124} mov bx,ax {02} mov Y,ax {009} shr bx,2 {16} add bx,ax {03} mov Y,bx {09} ------ ----- 145 42 Násobení 320 lze také provést například instrukcemi shl ax,6 a shl bx,8 pokud pracujete s proměnnými typu integer. Z obou příkladů je vidět, že takováto optimalizace dokáže urychlit výsledný průběh programu až pětkrát, takže pokud se vám ve vnitřní smyčce vyskytují podobné konstanty, nahraďte je výše zmíněnými instrukcemi a získáte tak cenné takty pro časově náročné mul a div, které už jen tak neodstraníte. Za zmínku stojí i fakt, že v současné době už většina programátorů optimalizuje pro Pentium, protože má jednu výbornou vlastnost pokud mu pošlete ke zpracování po sobě jdoucí stejné instrukce, vykoná je najednou, takže pokud se ve vaší smyčce vyskytuje například více mul a div instrukcí je dobré je pokud možno zařadit za sebe. Další výrazné urychlení docílíte vhodným použitím instrukcí typu movs a stos. Používají se při hromadném přesouvání dat nebo vyplňování paměťových oblastí stejnou hodnotou. Používejte instrukce s největším objemem dat jako movsd a stosd, pokud nejste omezeni procesorem. Při přepisování si ani neuvědomíte, že už vlastně optimalizujete, protože Pascal některé části programu generuje velice obecně, takže pokud využijete například hodnoty v registru ax pro tři operace získáte tím až 20 taktové urychlení. Dále je velice výhodné (pokud to jde) optimalizovat v každé situaci, takže notoricky známe xor ax,ax místo mov ax,0 nebo inc ax, inc ax místo add ax,2 se určitě vyplatí. Problematika low-level optimalizace je velice zajímavá věc a určitě stojí za to se jí více zabývat. V následujících příkladech vám přináším ukázku, jak by asi měla vypadat optimalizace jednoduché funkce na kreslení čáry pomocí Bresenhamova algoritmu. Nejdříve uvádím její hi-level podobu a následuje vysoce optimalizovaná procedura pro speciální případ horizontální čáry a pak pro čáru nakreslenou mezi dvěma obecnými body [x1,y1] a [x2,y2]. Takže si je pilně prostudujte a možná přijdete i na to, jak by se daly ještě více zoptimalizovat, je to jen otázka nápadu. Na úplný závěr přikládám malý rezidentní prográmek v Pascalu, který má jednu zajímavou vlastnost, pokud jej spustíte, asi si už nezahrajete nějakou hru běžící v režimu 320x200x256. Je to docela dobrý joke pro notorické hráče, zkuste jej nenápadně vepsat do autoexecu nějakému vašemu známému, který tráví většinu svého volného času hraním her, pravděpodobně mu tím způsobíte abstinenční záchvat. ReDox -> příklady <- no13h.pas výheň