------------------Uwaga! Fragmenty w >...< pogrubione--------------- Jak ulepszyê procedurë? (cz. 3.) -------------------------------- OPTYMALIZACJA NA MC68020 Dzisiaj nareszcie zajmiemy sië problemem optymalizacji naszych procedur z wykorzystaniem specyficznych cech procesora Motorola 68020, które to umoûliwiajâ przyspieszenie zoptymalizowanego juû kodu w stosunku do kodu napisanego dla procesora Motorola 68000. Let's go! Miklesz/Damage Zacznë od spraw ogólnych, by na koïcu artykuîu przedstawiê przykîady. A zatem, przypomnijmy sobie, co mamy nowego lub zmodyfikowanego, a jednoczeônie opîacalnego w uûyciu? Przy konwersji liczb z normalnego formatu na BCD i na odwrót mamy dwie instrukcje: PACK oraz UNPACK. Radzë z nimi poeksperymentowaê! Zmieniî sië czas wykonywania instrukcji przesuniëê bitowych. W chwili obecnej wolniejsze sâ przesuniëcia arytmetyczne: ASR.a i ASL.a, natomiast szybsze sâ przesuniëcia logiczne: LSR.a i LSL.a. Ponadto wszystkie instrukcje z danej grupy przesuniëê wykonujâ sië z tâ samâ prëdkoôciâ. Co to oznacza w praktyce? Przede wszystkim to, ûe jedynie instrukcje: aSL.b #1,Dc warto zamieniaê na: ADD.b Dc,Dc Mamy takûe dostëp do absolutnej nowoôci: instrukcji na polach bitowych. Na przykîad instrukcja BFINS jest znacznie szybsza od odpowiadajâcej jej kombinacji MOVE, OR i AND. Ale tu uwaga, nie we wszystkich wypadkach, radzë sprawdziê samemu, gdyû na rozwaûanie wszystkich trybów adresowania nie starczyîoby objëtoôci tego numeru. Natomiast BFINS jest niewâtpliwie bardzo wygodnâ instrukcjâ, która na pewno "zoptymalizuje" nam czas poôwiëcony na napisanie rutynki. Jeûeli potrzebujesz postawiê "ileô tam" punktów i zaleûy Ci na czasie, sprawdú wczeôniej szybkoôê, nim uûyjesz BFINS. Jeûeli chcesz jednak tylko coô przetablicowaê, to wal ômiaîo! Polecam teû uûywanie BFEXTS (do "wyciâgania" pola bitowego ze znakiem) i BFEXTU (to samo, ale bez znaku). Za pomocâ BFFFO moûesz znaleúê najstarszy, zapalony, bit pola bitowego, a uûywajâc BFCLR, BFCHG i BFSET kasowaê, negowaê lub ustawiaê pole bitowe. Ale przestrzegam jeszcze raz, najpierw sprawdú szybkoôê dla danego trybu adresowania. Przy okazji warto zauwaûyê, ûe na MC68020 istniejâ instrukcje, które sië pozornie nie zmieniîy, lecz majâ teraz wiëksze rozmiary offsetów. Pozornie nie zmienione instrukcje TST, CMP oraz nowa CMP2 dziaîajâ teraz równieû z uûyciem adresowania wzglëdem licznika programu, o czym warto pamiëtaê... Oprócz tego wprowadzono nowâ instrukcjë: EXTB, która to "rozszerza" nam zapisanâ bezpoôrednio w bajcie wartoôê do dîugiego sîowa. Jest znacznie szybsza niû uûycie kombinacji dwóch innych instrukcji: EXT.W, a nastëpnie EXT.L. Czy ktoô z Was próbowaî wykonaê mnoûenie dwóch 32-bitowych wartoôci na procesorze MC68000? Trzeba byîo kombinowaê jak koï pod górkë, co nie? Procedurka zajmowaîa "trochë" linii i miaîa raczej charakter ciekawostki niû normalnego "odpowiednika" instrukcji. Teraz mamy MC68020, i cóû? Odpowiednia instrukcja zaîatwia nam wszystko za jednym zamachem! Moûemy mnoûyê 32 bity przez 32 bity, i otrzymaê wynik 32-bitowy lub 64-bitowy, oraz dzieliê 64 bity lub 32 bity przez 32 bity. Wzrost prëdkoôci jest oczywisty, to chyba jasne! Na tym koïczâ sië nowe instrukcje, które mogâ wpîynâê na szybkoôê dziaîania naszych procedur. Pozostaîo jednak kilka innych ciekawych cech procesora Motorola 68020, które warto omówiê i które moûemy wykorzystaê. Kiedy zabraknie nam wolnych rejestrów adresowych, cóû robimy? Na MC68000 kombinujemy poprzez zapisywanie na stos lub przez podobne machinacje. A na MC68020 po prostu uûywajâc poôredniego trybu adresowania przyjmujemy komórkë pamiëci, jak rejestr adresowy, i sprawë mamy z gîowy. Oczywiôcie prëdkoôê spada, ale to juû mniej waûne. Jednakûe moûe sië przydarzyê, ûe brakuje nam tylko rejestrów adresowych, a rejestrów danych mamy w bród... Wtedy procesor MC68020 przyjmie nam tryb adresowania wzglëdem rejestru danych, czyli: (Da), gdzie a naleûy do przedziaîu [0;7]. Tym razem takie adresowanie bëdzie wolniejsze od (Aa) jedynie o 3 cykle. Jak wiëc widzicie na podstawie dwóch ostatnich przykîadów, mamy teraz osiem szybkich rejestrów, osiem trochë wolniejszych rejestrów adresowych, emulowanych w rejestrach danych, oraz w krytycznych sytuacjach juû dosyê wolnâ caîâ pamiëê. Pamiëtajcie jednak, ûe bardzo czësto wystarczy umiejëtniej gospodarowaê rejestrami lub chwilowo zachowaê gdzieô stos i uûywaê jedynie rejestrów adresowych. Jeûeli jeszcze o tym nie wiecie, to spieszë donieôê, ûe procesor MC68000 zezwala na adresowanie z 16-bitowym przesuniëciem wzglëdem podstawowego rejestru adresowego. Na MC68000 moûliwe byîo tylko przesuniëcie 8-bitowe. Jeûeli uûywamy 16-bitowego przesuniëcia, to warto zauwaûyê, ûe instrukcja wykonywana z cache'a nie jest przy tym wolniejsza ani o jeden cykl w stosunku do odpowiednika z 8 bitami, natomiast wykonywana z pamiëci jest wolniejsza tylko o jeden cykl. Co wiëcej, moûemy uûywaê teû i 32-bitowych przesuniëê, lecz te zabiorâ nam kolejne cztery cykle instrukcji... Warto tu zauwaûyê, ûe w wiëkszoôci dobrych asemblerów nie musimy podawaê rozmiaru po wartoôci przesuniëcia, gdyû przy asemblacji i tak wybrany zostanie najkorzystniejszy tryb. Radzë to jednak sprawdziê, aby sië póúniej nie okazaîo, ûe niepotrzebnie operujemy caîy czas na dîugich sîowach. Pamiëtajcie teû, ûe czasami moûna uûyê mniejszego przesuniëcia poprzez odpowiednie ulokowanie danych. Jak zapewne juû wiecie, procesor MC68020 umoûliwia nam skalowanie przesuniëê opartych na rejestrach adresowych. Jest to zupeînie nowy tryb adresowania, którego radzë Wam uûywaê. Skala moûe mieê wartoôê 1, 2, 4 lub 8. Przy tym warto zauwaûyê, ûe niezaleûnie od uûytej skali, instrukcja wykonuje sië z tâ samâ prëdkoôciâ. Poniûej przedstawiam przykîad uûycia skalowanych danych: ASL.a #b,Dc -> MOVE.d (Ae,Dc.a*b),f MOVE.d (Ae,Dc.a),f Oczywiôcie b moûe przyjmowaê wartoôci: {1;2;4;8}. Ten nowy sposób adresowania jest bardzo przydatny przy wszelkiego rodzaju tablicach, copper-listach, listach adresów lub bardziej zîoûonych strukturach danych. Skalowanie moûe byê uûyte zarówno w operandzie úródîowym, jak teû i docelowym. Naturalnie, kiedy nie uûywamy znaku *, procesor automatycznie przyjmie skalë=1. Jednakûe kiedy piszemy na nowym procesorze, kod pod MC68000, nie wolno uûywaê znaku *, gdyû skalowanie nie jest rozszerzonâ wersjâ skalowania MC68000, lecz zupeînie nowâ funkcjâ, której MC68000 nie ma. Tak na marginesie, zapytacie pewnie dlaczego akurat skala 1, 2, 4 i 8, a nie, powiedzmy, 3, 5, 6? Otóû zauwaûcie, ûe procesor w tym wypadku musiaîby sobie wewnëtrznie te dane przemnoûyê, co wpîynëîoby na szybkoôê wykonywania instrukcji! Podsumujmy wiadomoôci o nowym trybie adresowania: * Procesor Motorola 68020 oferuje nam 18 trybów adresowania, w stosunku do 12 trybów Motoroli 68000. * Nowa Motorola umoûliwia adresowanie "poôrednie", które moûe byê czasami uûyteczne. * Mamy teraz moûliwoôê stosowania wiëkszego rozmiaru przesuniëê, co w wypadku duûych tablic daje nam szansë przyspieszenia naszych procedur. * Uzyskujemy moûliwoôê "skalowania" przesuniëê, zawartych w rejestrach adresowych, zastosowanie -- oczywiste. Na koniec zajmë sië jeszcze jednym problemem, a mianowicie czasem dostëpu do poszczególnych typów pamiëci, których liczba zaleûy od typu komputera, zastosowanych rozszerzeï i typu procesora. Konfiguracjâ, którâ sië zajmë, bëdzie bardzo popularna dziô Amiga 1200 z pamiëciâ Fast. W takim modelu mamy do dyspozycji: Chip Memory, ROM, Cache Memory i Fast Memory. Omówmy je zatem. >Chip Memory.< Jest to standardowa pamiëê kaûdej Amigi, w naszym wypadku jest jej 2 MB. Dostëp do niej majâ wszystkie typy ukîadów komputera. Moûna przechowywaê tu zarówno kody programów, jak teû dane. Jest to bardzo wolna pamiëê, wiëc polecam uûywaê jej tylko wtedy, kiedy jest to konieczne. >ROM.< Kaûdy przedszkolak wie, ûe do ROM-u nic nie moûna zapisaê (na ogóî). Po co wiëc go omawiam? Otóû warto zwróciê uwagë na to, ûe ROM jest szybszy od Chip Memory, wiëc wykonywanie sië kodu z ROM-u trwa krócej. A przecieû w ROM-ie mamy zapisane gotowe procedurki, które mogâ sië nam przydaê przy kodowaniu. Moûemy takûe wykorzystywaê dane zawarte w ROM-ie, choê ma to juû mniejszy sens. Tak wiëc jeôli masz umieôciê swój kod w Chip Memory, spróbuj znaleúê i uûyê odpowiadajâcej mu procedurki z posiadanego przez Ciebie 0,5 MB ROM-u, a nuû bëdzie to szybsze rozwiâzanie. >Cache Memory.< Jest to pamiëê, do której bezpoôrednio równieû nic nie moûemy zapisaê ani odczytaê z niej, jednakûe procesor automatycznie przepisuje sobie do niej swój wykonujâcy sië kod. Mamy 256 B pamiëci Cache. Tutaj uwaga, w naszym wypadku jest ona przeznaczona wyîâcznie na kod, a nie na dane, jak ma to miejsce w nowszych Motorolach. Co daje nam Cache Memory. Znaczny wzrost prëdkoôci programu, wykonujâcego sië z niej w porównaniu do, np. Chip Memory. Radzë wiëc tak konstruowaê wszelkie pëtle, aby w caîoôci mieôciîy sië w Cache Memory! >Fast Memory.< Na koniec zostawiîem sobie ten najbardziej uûyteczny typ pamiëci. Amiga wyposaûona w Fast Memory pracuje standardowo o ok. 2,14 raza szybciej. Standardowy procesor Amigi 1200, wykonujâcy kod znajdujâcy sië w Fast Memory, dziaîa z prëdkoôciami dochodzâcymi do 3 MIPS-ów, co utalentowanemu koderowi pozwoli na tworzenie efektów, znanych np. z pecetycznych gierek typu Doom czy Comanche. Naleûy zauwaûyê, ûe dostëp do pamiëci Fast Memory ma tylko procesor gîówny, tak wiëc wszelkie bezpoôrednie wyôwietlanie grafiki, bâdú odtwarzanie sampli z Fast Memory jest niemoûliwe! W tym momencie przerywam opis typów pamiëci, by juû za miesiâc zajâê sië ich praktycznym wykorzystaniem spod poziomu asemblera.