Komputery CISC i RISC f& przez wiele lat wzrost wydajnoÅ›ci procesorów starano siÄ™ uzyskać poprzez zwiÄ™kszanie wielkoÅ›ci i zÅ‚ożonoÅ›ci list rozkazów, jak również poprzez instalowanie bloków funkcjonalnych, wspomagajÄ…cych procesor (np. pamięć podrÄ™czna); f& badania różnych kompilatorów jÄ™zyków programowania pokazaÅ‚y jednak, że tylko niewielki podzbiór rozkazów procesora jest używany przez kompilatory; przykÅ‚adowo, kompilatory jÄ™zyka C firmy Sun i GNU nie używaÅ‚y 71% instrukcji procesora Motorola 68020; dalsze badania innych procesorów pokazaÅ‚y, że najczęściej używane sÄ… rozkazy przesyÅ‚ania danych (46%), skoki (w tym wywoÅ‚ania i powroty z podprogramu) (27%), rozkazy arytmetyczne (14%), porównania (10%) i rozkazy logiczne (2%); f& pozornie, jeÅ›li lista rozkazów procesora zawiera rozkazy zawierajÄ…ce zÅ‚ożone operacje, to stanowi dużą wygodÄ™ dla autorów kompilatora, a wygenerowany kod jest krótszy; jednak doÅ›wiadczenia praktyczne pokazujÄ…, że zÅ‚ożone rozkazy maszynowe sÄ… czÄ™sto trudne do wykorzystania, ponieważ kompilator musi zidentyfikować te fragmenty kodu, które pasujÄ… dokÅ‚adnie do czynnoÅ›ci rozkazu powoduje znaczny wzrost zÅ‚ożonoÅ›ci kompilatora (zwÅ‚aszcza procedur optymalizacyjnych); ogólnie: kompilatory wykazujÄ… tendencjÄ™ do faworyzowania prostych rozkazów; f& również doÅ›wiadczenia praktyczne nie potwierdziÅ‚y przypuszczenia, że programy wykorzystujÄ…ce zÅ‚ożone instrukcje bÄ™dÄ… krótsze zwykle zawierajÄ… mniej instrukcji, ale zÅ‚ożone instrukcje kodowane sÄ… za pomocÄ… wiÄ™kszej liczby bajtów, tak że rozmiary programu nie ulegajÄ… istotnemu zmniejszeniu; f& w powstaÅ‚ej sytuacji zaproponowano ograniczenie listy rozkazów, uproszczenie kodowania, co pozwoliÅ‚oby na szybsze ich wykonywanie w rezultacie podjÄ™tych prac uksztaÅ‚towaÅ‚a siÄ™ architektura procesorów o zredukowanych listach rozkazów, znanych jako RISC (ang. Reduced Instruction Set Computer); jednoczeÅ›nie, istniejÄ…ce procesory, o rozbudowanych listach rozkazów zaliczono do typu CISC (ang. Complex Instruction Set Computer); f& jako charakterystyczne cechy architektury CISC wymienia siÄ™ zazwyczaj: " lista rozkazów zawiera 100 ÷ 250 pozycji, wÅ›ród których wystÄ™pujÄ… rozkazy realizujÄ…ce zÅ‚ożone funkcje; " dostÄ™pna jest duża liczba trybów adresowania 5 ÷ 20; " czasy wykonania poszczególnych rozkazów, w zależnoÅ›ci od stopnia skomplikowania, zmieniajÄ… siÄ™ w dość szerokich granicach; " realizacja rozkazów oparta jest na technice mikroprogramowania; f& z kolei dla procesorów RISC charakterystyczne sÄ… poniższe cechy: " stosunkowo niewiele trybów adresowania; " formaty rozkazów staÅ‚ej dÅ‚ugoÅ›ci, Å‚atwe do zdekodowania; " dostÄ™p do pamiÄ™ci operacyjnej umożliwiajÄ… tylko dwa rozkazy: load, store; " stosunkowo obszerny zbiór rejestrów ogólnego przeznaczenia; " rozkazy wykonujÄ… dziaÅ‚ania na argumentach zapisanych w rejestrach (a nie w pamiÄ™ci operacyjnej); " sterowanie wykonywaniem rozkazów realizowane jest ukÅ‚adowo (nie mikroprogramowo); " intensywne wykorzystanie przetwarzania potokowego (wystÄ™puje też w innych, nowoczesnych procesorach); także kompilatory generujÄ… kod uwzglÄ™dniajÄ…cy wymagania przetwarzania potokowego. Rejestry ogólnego przeznaczenia w procesorach RISC f& współczesne procesory sÄ… w stanie przetwarzać dane z szybkoÅ›ciÄ… wiÄ™kszÄ… niż szybkość pamiÄ™ci głównej (operacyjnej), co może powodować przestoje procesora; znaczne usprawnienie komunikacji procesora i pamiÄ™ci głównej przyniosÅ‚o wprowadzenie pamiÄ™ci podrÄ™cznych, ale nadal komunikacja ta stanowi wÄ…skie gardÅ‚o; f& procesory RISC majÄ… zazwyczaj duże zestawy rejestrów ogólnego przeznaczenia (nazywanych też rejestrami uniwersalnymi) i do zadaÅ„ obliczeniowych używajÄ… tylko rejestrów, a nie rejestrów i pamiÄ™ci; w rezultacie potrzeba mniej dostÄ™pów do pamiÄ™ci i problem komunikacji procesora z pamiÄ™ciÄ… staje siÄ™ mniej krytyczny; f& zazwyczaj dÅ‚ugość sÅ‚owa rozkazu jest równa szerokoÅ›ci magistrali danych, wiÄ™c każdy rozkaz może być pobrany w jednym cyklu pamiÄ™ci (w procesorach CISC rozkazy czÄ™sto muszÄ… być pobierane w czasie kilku cykli pamiÄ™ci); f& w niektórych procesorach RISC używane sÄ… oddzielne pamiÄ™ci dla rozkazów i danych (tzw. architektura harwardzka), z których każda obsÅ‚ugiwana jest przez oddzielne magistrale adresowe i danych. Przekazywanie parametrów do podprogramów w procesorach RISC f& w programach kodowanych w jÄ™zykach wysokiego poziomu procedury i funkcje wywoÅ‚ujÄ… czÄ™sto inne procedury i funkcje, a także same sÄ… wywoÅ‚ywane; w dalszej używać bÄ™dziemy terminu procedura także w znaczeniu funkcji; f& w procesorach CISC parametry wywoÅ‚aÅ„ przekazywane sÄ… zazwyczaj przez stos, co wymaga wielu odwoÅ‚aÅ„ do pamiÄ™ci; z kolei w procesorach RISC duża liczba rejestrów ogólnego przeznaczenia umożliwia przekazywanie parametrów przez rejestry, co znacznie zmniejsza liczbÄ™ odwoÅ‚aÅ„ do pamiÄ™ci; f& procedura wykonuje dziaÅ‚ania: " na parametrach przekazanych jej podczas wywoÅ‚ywania; " na zmiennych lokalnych, w których zapisywane sÄ… wyniki poÅ›rednie; " na zmiennych globalnych, dostÄ™pnych także dla innych funkcji w procesorach RISC wszystkie te zmienne i parametry przechowywane sÄ… w rejestrach, zorganizowanych w postaci tzw. okien; w typowych rozwiÄ…zaniach okno zawiera 32 rejestry, a liczba okien wynosi np. 16; f& każda procedura korzysta z wÅ‚asnego okna rejestrów, przy czym okna sÄ…siednich procedur (w sensie wywoÅ‚ywania) częściowo siÄ™ nakÅ‚adajÄ…, co uÅ‚atwia przekazywanie parametrów; f& wywoÅ‚anie procedury powoduje automatyczne przeÅ‚Ä…czenie procesora do użycia innego okna rejestrów; w dowolnej chwili widzialne i adresowalne jest tylko jedno okno rejestrów, tak jak gdyby istniaÅ‚ tylko jeden zestaw rejestrów; f& najpierw rozpatrzymy wersjÄ™ uproszczonÄ… bez rejestrów przeznaczonych dla zmiennych globalnych; okno podzielone jest na trzy obszary o staÅ‚ych rozmiarach obejmujÄ…ce: " rejestry parametrów (zawierajÄ… parametry przekazane przez procedurÄ™ wywoÅ‚ujÄ…cÄ…, oraz wyniki, które majÄ… być przekazane z powrotem); " rejestry lokalne (używane do przechowywania zmiennych lokalnych procedury); " rejestry tymczasowe (używane do wymiany parametrów i wyników z nastÄ™pnym niższym poziomem, innymi sÅ‚owy z procedurÄ… wywoÅ‚anÄ… przez procedurÄ™ bieżącÄ…); Rejestry Rejestry Rejestry Poziom parametrów lokalne tymczasowe zagnieżdżenia J WywoÅ‚anie/powrót Poziom Rejestry Rejestry Rejestry zagnieżdżenia J + 1 parametrów lokalne tymczasowe f& rejestry tymczasowe sÄ… jednego poziomu sÄ… fizycznie tymi samymi rejestrami, co rejestry parametrów nastÄ™pnego niższego poziomu; zatem procedura przygotowuje najpierw parametry wywoÅ‚ania w rejestrach tymczasowych, a nastÄ™pnie wywoÅ‚uje żądanÄ… procedurÄ™ po wywoÅ‚aniu procedury nastÄ™puje automatyczne przeÅ‚Ä…czenie procesora do nastÄ™pnego okna, a rejestry tymczasowe w aktualnym oknie sÄ… widoczne jako rejestry parametrów; f& w procesorach RISC liczba rejestrów ogólnego przeznaczenia (tworzÄ…cych okna) jest dość duża, ale nie wystarczajÄ…ca przy dużych gÅ‚Ä™bokoÅ›ciach zagnieżdżenia; w takich przypadku argumenty starszych procedur muszÄ… być zapisywane w pamiÄ™ci, i odtwarzane pózniej, gdy maleje gÅ‚Ä™bokość zagnieżdżenia; f& niektóre zmienne w programie majÄ… charakter globalny i powinny być dostÄ™pne dla wszystkich procedur; zazwyczaj zmienne takie lokowane sÄ… w pamiÄ™ci operacyjnej, co może być nieefektywne przy dużej liczbie odwoÅ‚aÅ„; w procesorach RISC wydziela siÄ™ pewnÄ… liczbÄ™ rejestrów do przechowywania zmiennych globalnych sÄ… one dostÄ™pne w każdym oknie; jednak nierzadko liczba zmiennych globalnych jest wiÄ™ksza od liczby rejestrów i kompilator musi wybrać zmienne globalne najczęściej używane; ten sam problem wystÄ™puje także, gdy liczba zmiennych lokalnych procedury przekracza liczbÄ™ rejestrów (np. 8) w rozwiÄ…zaniach tego problemu korzysta siÄ™ z algorytmów kolorowania grafów; f& stosowany jest zunifikowany schemat numerowania rejestrów: Nr rejestru Przeznaczenie zmienne globalne 0 ÷ 7 rejestry tymczasowe 8 ÷ 15 zmienne lokalne 16 ÷ 23 parametry 24 ÷ 31 w rezultacie każda procedura ma dostÄ™p do pojedynczego okna, zawierajÄ…cego identycznie oznaczone rejestry; f& wprowadzenie dużej liczby rejestrów w procesorach RISC może być traktowane jako rozwiÄ…zanie podobne do pamiÄ™ci podrÄ™cznej każde z nich ma pewne wady i zalety; w programach o niewielkim stopniu zagnieżdżenia procedur, rejestry procesora pozostajÄ… częściowo niewykorzystane; z kolei pamięć podrÄ™czna może dynamicznie reagować na rozwój sytuacji, ale dane do pamiÄ™ci podrÄ™cznej wczytywane sÄ… blokami, które tylko częściowo sÄ… wykorzystywane; uważa siÄ™ jednak, że adresowanie rejestrów jest dość proste, w porównaniu do bardziej zÅ‚ożonego mechanizmu adresowania pamiÄ™ci, wskutek czego stosowanie dużej liczby rejestrów jest bardziej efektywne. Sterowanie mikroprogramowe i ukÅ‚adowe f& w ujÄ™ciu skrótowym, wykonywanie rozkazu przez procesor rozpoczyna siÄ™ Rejestry Jednostka pobrania rozkazu z pamiÄ™ci, procesora sterujÄ…ca po czym identyfikowany jest jego kod na tej podstawie jednostka sterujÄ…ca w procesorze wydaje odpo- Jednostka wiednie dyspozycje dla jednostki arytmetyczno- arytm. logiczna logicznej, rejestrów i innych podzespołów procesora, kierujÄ…c odpowiednio przepÅ‚ywem i przetwarzaniem danych, zgodnie rozpoznanym kodem rozkazu; f& istniejÄ… dwa podstawowe sposoby konstrukcji jednostki sterujÄ…cej procesora: jednostka sterujÄ…ca mikroprogramowalna i jednostka sterujÄ…ca ukÅ‚adowa; f& koncepcjÄ™ sterowania mikroprogramowanego można okreÅ›lić jako sterowanie za pomocÄ… wewnÄ™trznego procesora, wbudowanego w główny procesor; wewnÄ™trzny mikroprocesor zawiera wÅ‚asny wskaznik instrukcji (licznik rozkazów) i wykonuje mikroprogram zapisany w pamiÄ™ci ROM (lub w tablicy logicznej PLA ang. programmed logic array); f& mikroprogram skÅ‚ada siÄ™ z szeregu mikrorozkazów, a każdy mikrorozkaz zawiera sekwencjÄ™ bitów, która reprezentuje mikrooperacjÄ™ sterujÄ…cÄ… przemieszczaniem informacji miÄ™dzy różnymi podzespoÅ‚ami i rejestrami procesora; wÅ›ród mikrorozkazów istniejÄ… także skoki warunkowe i bezwarunkowe, zmieniajÄ…ce kolejność, w jakiej wykonywane sÄ… mikrorozkazy; f& w tym kontekÅ›cie rozkazy zwykÅ‚ego programu wykonywanego przez procesor nazywane sÄ… makrorozkazami; termin makrorozkazy używany jest także w innym znaczeniu w jÄ™zykach programowania i opisuje instrukcje zastÄ™powane w treÅ›ci programu przez teksty makrodefinicji; f& ponieważ wiele mikroprogramów wymaga jednakowych sekwencji mikrorozkazów, używane sÄ… także mikroprocedury; f& sterowanie mikroprogramowe umożliwia stosunkowe Å‚atwe tworzenie nowych wersji procesorów o bardziej rozbudowanej liÅ›cie rozkazów; ze wzglÄ™du na postÄ™py technologii elektronicznej rozmiary kolejnych wersji procesorów pozostajÄ… czÄ™sto niezmienione; ponadto konstrukcje ze sterowaniem mikroprogramowym pozwalajÄ… na wzglÄ™dnie Å‚atwe usuwanie bÅ‚Ä™dów projektowych na etapie prototypowym; f& sterowanie ukÅ‚adowe stanowi zÅ‚ożony ukÅ‚ad cyfrowy zawierajÄ…cy bramki, przerzutniki i inne podzespoÅ‚y; istotnym elementem takiego sterowania jest licznik sekwencji, który jest zwiÄ™kszany o 1 w kolejnych fazach wykonania rozkazu; po zaÅ‚adowaniu kolejnego rozkazu do rejestru rozkazów bity kodu operacji wraz licznikiem sekwencji podawane sÄ… na wejÅ›cie ukÅ‚adu logicznego, który generuje odpowiednie sygnaÅ‚y sterujÄ…ce; f& sterowanie ukÅ‚adowe pozwala zazwyczaj na nieco szybsze wykonywanie rozkazów; na poziomie projektowania, sterowanie ukÅ‚adowe jest mniej elastyczne niż mikroprogramowe i projekty nie mogÄ… Å‚atwo modyfikowane; f& sterowanie ukÅ‚adowe nie może być stosowane ze zÅ‚ożonymi formatami rozkazów. Przetwarzanie potokowe f& przetwarzanie potokowe stanowi pewnÄ… technikÄ™ wykonywania rozkazów etapami, co umożliwia przyspieszenie pracy procesora; przetwarzanie potokowe rozkazów jest podobne do użycia linii montażowej w zakÅ‚adzie produkcyjnym możliwa jest jednoczesna praca nad wyrobami w różnych stadiach produkcji; w potoku na jednym koÅ„cu przyjmowane sÄ… nowe elementy wejÅ›ciowe, zanim jeszcze elementy poprzednio przyjÄ™te ukażą siÄ™ na wyjÅ›ciu; f& przetwarzanie potokowe jest stosowane w różnych typach procesorów, zarówno o architekturze CISC (Motorola 68K, Pentium), jak i w procesorach o zredukowanej liczbie rozkazów (RISC); jednak uzyskanie przyspieszenia wymaga przygotowania odpowiedniego kodu przez kompilatory, które w przypadku architektury CISC zazwyczaj nie uwzglÄ™dniajÄ… specyfiki przetwarzania potokowego; f& można przyjąć, że każdy etap zajmuje jeden cykl zegarowy; procesor przyjmuje nowy rozkaz do potoku po każdym cyklu zegara, po czym rozkaz przechodzi kolejno przez poszczególne etapy; taka realizacja nie skraca czasu wykonywania rozkazu, ale zwiÄ™ksza caÅ‚kowitÄ… przepustowość, powodujÄ…c zakoÅ„czenie jednego rozkazu po każdym cyklu zegara; f& liczba etapów realizacji rozkazu zależy od konstrukcji procesora, ale podstawowe znaczenie majÄ… cztery etapy: " pobranie rozkazu (ang. instruction fetch), stanowi etap, w którym rozkaz pobierany jest z pamiÄ™ci głównej albo z pamiÄ™ci podrÄ™cznej; " dekodowanie rozkazu (ang. instruction decode) rozkaz jest dekodowany, przy czym identyfikuje siÄ™ argumenty zródÅ‚owe, które przepisywane sÄ… do rejestrów pomocniczych wejÅ›ciowych procesora (niedostÄ™pnych na poziomie programowania); " wykonanie rozkazu (ang. execution) procesor wykonuje operacje na argumentach zapisanych w rejestrach pomocniczych, a uzyskane wyniki zapisuje do rejestrów pomocniczych wyjÅ›ciowych; " zapisanie wyników (ang. write-back) stanowi etap, w którym zawartoÅ›ci rejestrów pomocniczych wyjÅ›ciowych zostajÄ… skopiowane do zwykÅ‚ych rejestrów procesora lub do lokacji pamiÄ™ci; Cykl Etapy Pobranie Dekodo-wanie Wykonanie Zapisanie rozkazu rozkazu rozkazu wyników rozkazu 1 Rozkaz 1 2 Rozkaz 2 Rozkaz 1 3 Rozkaz 3 Rozkaz 2 Rozkaz 1 4 Rozkaz 4 Rozkaz 3 Rozkaz 2 Rozkaz 1 5 Rozkaz 5 Rozkaz 4 Rozkaz 3 Rozkaz 2 f& w procesorach klasy CISC dekodowanie rozkazu jest bardziej zÅ‚ożone i z tego wzglÄ™du przedstawiane jest w trzech etapach: " wÅ‚aÅ›ciwe dekodowanie rozkazu obejmuje okreÅ›lenie kodu operacji i specyfikatorów argumentów; " obliczanie argumentów obejmuje obliczanie adresu efektywnego każdego argumentu zródÅ‚owego (z ewentualnym wykorzystaniem rejestrów modyfikacji adresowych, adresowania poÅ›redniego itp.); " pobieranie argumentów pobranie argumentów z pamiÄ™ci lub z rejestrów i przepisanie do rejestrów pomocniczych wejÅ›ciowych; f& po zapeÅ‚nieniu potoku, po każdym cyklu zegarowym zostaje zakoÅ„czony jeden rozkaz dla podanego przykÅ‚adu współczynnik przyspieszenia wynosi 4; warto dodać, poszczególne rozkazy wykonywane sÄ… zazwyczaj w ciÄ…gu kilku cykli zegarowych, natomiast producenci procesorów podajÄ… liczbÄ™ cykli potrzebnych dla wykonania poszczególnych rozkazów przy zaÅ‚ożeniu, że rozkaz stanowi jeden z wielu kolejno wykonywanych rozkazów; zatem wartoÅ›ci tej nie należy traktować jako czasu wykonywania rozkazu, ale raczej jako miarÄ™ wydajnoÅ›ci procesora (gotowe samochody w fabryce pojawiajÄ… siÄ™ co dwie minuty, ale montaż pojedynczego samochodu trwa wiele godzin); f& istniejÄ… różne przyczyny, które powodujÄ… zmniejszenie współczynnika przyspieszenia: " realizacja niektórych etapów może powodować konflikty dostÄ™pu do pamiÄ™ci; " jeÅ›li czasy trwania poszczególnych etapów mogÄ… być niejednakowe, to na różnych etapach wystÄ…pi pewne oczekiwanie; " w programie wystÄ™pujÄ… skoki (rozgaÅ‚Ä™zienia) warunkowe, które mogÄ… zmienić kolejność wykonywania instrukcji, a tym samym unieważnić kilka pobranych rozkazów muszÄ… one być usuniÄ™te z potoku, a potok musi być zapeÅ‚niony nowym strumieniem rozkazów; " wystÄ…pienie przerwania sprzÄ™towego lub wyjÄ…tku procesora stanowi zdarzenie nieprzewidywalne i również pogarsza przetwarzanie potokowe; " niektóre rozkazy wymagajÄ… dodatkowych cykli (np. do Å‚adowania danych); " czasami rozkazy muszÄ… oczekiwać z powodu zależnoÅ›ci od nie zakoÅ„czonych poprzednich rozkazów system musi zawierać rozwiÄ…zania zapobiegajÄ…ce tego rodzaju konfliktom; f& różne zródÅ‚a zakłóceÅ„ przetwarzania potokowego nazywane sÄ… hazardami; f& w trakcie wykonywania poszczególnych instrukcji używane sÄ… rozmaite bloki funkcjonalne i podzespoÅ‚y komputera, jak pamięć operacyjna i podrÄ™czna, magistrale, zbiory rejestrów, jednostka arytmetyczno-logiczna procesora i inne stanowiÄ… one zasoby komputera, które muszÄ… być odpowiednio udostÄ™pniane (dzielone) miÄ™dzy rozkazami znajdujÄ…cymi siÄ™ w potoku procesora; f& jeÅ›li dwa etapy potrzebujÄ… dostÄ™pu do tego samego zasobu w tym samym czasie, to potok musi zostać zamrożony do czasu rozwiÄ…zania konfliktu, co prowadzi do zwiÄ™kszenia liczby cykli potrzebnych do realizacji rozkazu; f& problemy można rozwiÄ…zać poprzez zainstalowanie dwóch lub wiÄ™cej modułów sprzÄ™towych tego samego typu, np. używane sÄ… podwójne bufory do pobierania rozkazów, stosuje siÄ™ także oddzielne pamiÄ™ci podrÄ™czne dla rozkazów i danych; f& inny problem stanowiÄ… zależnoÅ›ci danych: 1. odczyt po zapisie operacja odczytu, np. rejestru przez rozkaz, który nastÄ™puje po rozkazie dokonujÄ…cym zapisu, może być przeprowadzona dopiero po zakoÅ„czeniu zapisu; 2. zapis po odczycie operacja zapisu rejestru może być wykonana dopiero wówczas, gdy poprzedni rozkaz, odnoszÄ…cy siÄ™ do tego rejestru, wykonaÅ‚ odczyt; 3. zapis po zapisie rozkaz musi oczekiwać na zapisanie rejestru, jeÅ›li poprzedni rozkaz nie zrealizowaÅ‚ zapisu; f& na ogół zależnoÅ›ci danych mogÄ… być wyeliminowane w sposób programowy poprzez zmianÄ™ kolejnoÅ›ci rozkazów (ang. static scheduling szeregowanie statyczne), co można uzyskać poprzez odpowiedniÄ… kompilacjÄ™ pozwala to na wyeliminowanie okoÅ‚o 70% opóznieÅ„; f& stosowane jest także szeregowanie dynamiczne, realizowane sprzÄ™towo; w niektórych architekturach stosowana jest technika wyprzedzania argumentów (ang. operand forwarding), która polega na udostÄ™pnieniu dodatkowej Å›cieżki danych umożliwiajÄ…cej bezpoÅ›rednie przekazanie argumentu z rejestru pomocniczego wyjÅ›ciowego do rejestru pomocniczego wejÅ›ciowego, co przeciwdziaÅ‚a zamrożeniu potoku w sytuacji "odczyt po zapisie"; f& technika notowania (ang. scoreboarding) polega na doÅ‚Ä…czeniu do każdego rejestru jednobitowego znacznika: stan 1 tego znacznika wskazuje, że rejestr zawiera dane poprawne, stan 0 niepoprawne; jeÅ›li pobierany rozkaz zapisuje wynik do rejestru, to w trakcie dekodowania tego rozkazu znacznik zostaje ustawiony w stan 0; stan 0 sygnalizuje innym rozkazom, że zawartość rejestru zostanie zmieniona i zmusza te rozkazy do czekania; po wykonaniu rozkazu i uaktualnieniu zawartoÅ›ci rejestru znacznik ustawiany jest w stan 1, co umożliwia wznowienie zamrożonych rozkazów; omawiana technika stosowana jest w procesorze Motorola 88010. Konflikty sterowania f& w przetwarzaniu potokowym powinien być zapewniony staÅ‚y dopÅ‚yw rozkazów do poczÄ…tkowego etapu potoku; zasadniczÄ… przeszkodÄ… w realizacji tego postulatu jest rozkaz skoku (rozgaÅ‚Ä™zienia) warunkowego aż do zakoÅ„czenia wykonywania tego rozkazu nie jest możliwe stwierdzenie czy skok zostanie wykonany, czy nie; f& zatem rozkaz skoku warunkowego powoduje, że adres nastÄ™pnego rozkazu przewidzianego do pobrania jest nieznany; w tej sytuacji realizacja etapu pobierania mogÅ‚aby nastÄ…pić dopiero po zakoÅ„czeniu wykonywania rozkazu skoku warunkowego; zwiÄ…zana z tym strata czasu może być zmniejszona przez przewidywanie rozgaÅ‚Ä™zieÅ„ (zgadywanie); f& przewidywania statyczne nie zależą od historii wykonania rozkazu skoku; zwykle przyjmuje siÄ™ jedno z niżej wymienionych zaÅ‚ożeÅ„: " rozgaÅ‚Ä™zienie zawsze nie nastÄ…pi, tzn. warunek testowany przez rozkaz skoku nie bÄ™dzie speÅ‚niony i bÄ™dÄ… pobierane kolejne rozkazy za rozkazem skoku; " rozgaÅ‚Ä™zienie zawsze nastÄ…pi i należy pobrać kolejne rozkazy z lokacji pamiÄ™ci wskazanej przez adres rozkazu skoku (przez cel rozgaÅ‚Ä™zienia); " dla pewnych rozkazów sterujÄ…cych zakÅ‚ada siÄ™, że rozgaÅ‚Ä™zienie zawsze nastÄ…pi, dla innych przyjmuje siÄ™, że nie nastÄ…pi badania eksperymentalne pokazujÄ…, że metoda zapewnia prawdopodobieÅ„stwo sukcesu ponad 75%; f& jeÅ›li przewidywanie okaże siÄ™ nietrafne, to koniecznie jest unieważnienie częściowo przetworzonych rozkazów i wypeÅ‚nianie potoku od nowa; f& przewidywanie za pomocÄ… strategii dynamicznych oparte jest na historii wykonania rozkazów skoków warunkowych (rozgaÅ‚Ä™zieÅ„ warunkowych); zwykle z każdym rozkazem zwiÄ…zane sÄ… jeden lub dwa bity odzwierciedlajÄ…ce najnowszÄ… historiÄ™ rozkazu bity te pozwalajÄ… procesorowi podjąć odpowiedniÄ… decyzjÄ™ po ponownym natrafieniu na rozkaz; f& za pomocÄ… pojedynczego bitu historii rejestruje siÄ™ wystÄ…pienie lub niewystÄ…pienie skoku (rozgaÅ‚Ä™zienia) podczas ostatniego wykonania rozkazu; w pÄ™tli bÅ‚Ä™dne przewidywanie wystÄ…pi dwukrotnie: raz przy wejÅ›ciu do pÄ™tli i raz przy jej opuszczaniu; f& lepsze przewidywanie można uzyskać poprzez zastosowanie dwóch bitów, np. do zarejestrowania dwóch ostatnich przypadków wykonania rozkazu; jeÅ›li dwa ostatnie skoki zostaÅ‚y wykonane jednakowo, to przy nastÄ™pnym należy wybrać tÄ™ samÄ… Å›cieżkÄ™; jeÅ›li przewidywanie okazaÅ‚o siÄ™ bÅ‚Ä™dne, to pozostaje bez zmian aż do ponownego wykonania rozkazu dopiero dwa kolejne bÅ‚Ä™dne przewidywania powodujÄ… zmianÄ™ decyzji; f& dość skutecznym rozwiÄ…zaniem problemu predykcji skoków może być tablica historii skoków; tablica ta rejestruje wyniki dziaÅ‚ania rozkazów skokowych w celu przewidywania ich zachowania w przyszÅ‚oÅ›ci jest to szczególnie przydatne w odniesieniu do pÄ™tli programowych; jednak zawartość tablicy może być wykorzystana dopiero po zdekodowaniu adresu rozkazu skokowego; f& w procesorze Pentium używany jest bufor adresów rozgaÅ‚Ä™zieÅ„ BTB (ang. branch target buffer), w którym przechowywana jest historia 256 skoków warunkowych (rozgaÅ‚Ä™zieÅ„); f& gdy zostanie napotkany rozkaz skoku warunkowego, okreÅ›lany jest jego adres docelowy (efektywny), a nastÄ™pnie druga kolejka rozkazów rozpoczyna pobieranie instrukcji kierujÄ…c siÄ™ przewidywaniami na podstawie BTB; jeÅ›li przewidywanie nie sprawdziÅ‚o siÄ™, to obie kolejki sÄ… opróżniane i ponownie napeÅ‚niane; w Pentium przyjÄ™to, że jeÅ›li pÄ™tla wykonaÅ‚a skok, to w kolejnych iteracjach skok ten zostanie ponownie wykonany; f& stosowane sÄ… również inne rozwiÄ…zania zwiÄ…zane z przetwarzaniem rozkazów skokowych najważniejsze z nich omawiane sÄ… poniżej; f& niekiedy używane sÄ… dwa bufory typu FIFO, do których pobierane sÄ… rozkazy wykonywane w każdej z gaÅ‚Ä™zi rozwidlenia; w zależnoÅ›ci od wyniku skoku używany jest jeden lub drugi bufor; bufor zawierajÄ…cy nie używane rozkazy jest opróżniany po napotkaniu w strumieniu rozkazów kolejnego skoku warunkowego; metoda ta przestaje być skuteczna, gdy do bufora dostanie siÄ™ dwa lub wiÄ™cej rozkazów skoku warunkowego; f& technika zwielokrotnienia strumieni (stosowana, np. w komputerze IBM 370) polega na powieleniu poczÄ…tkowych części potoku i umożliwieniu równoczesnego pobrania obu sekwencji rozkazów za pomocÄ… dwóch strumieni; wystÄ™pujÄ… jednak pewne problemy: " konflikty w zakresie dostÄ™pu do rejestrów i pamiÄ™ci; " w potoku mogÄ… siÄ™ pojawić inne skoki warunkowe, zanim zostanie przesÄ…dzone oryginalne rozgaÅ‚Ä™zienie w tej sytuacji potrzebny jest jeszcze jeden strumieÅ„; f& bufor pÄ™tli jest podobny do pamiÄ™ci podrÄ™cznej przeznaczonej dla przechowywania rozkazów, ale jest znacznie mniejszy (np. 256 bajtów) i taÅ„szy; bufor pÄ™tli zawiera n ostatnio pobranych rozkazów, przy czym stosowane jest pobieranie z wyprzedzeniem, co oznacza, że w stadium wykonywania znajduje siÄ™ tylko poczÄ…tkowa część rozkazów zawartych w buforze; w przypadku wystÄ…pienia rozkazu skoku wewnÄ…trz niedużej pÄ™tli adres rozkazu wskazywać bÄ™dzie na rozkaz znajdujÄ…cy siÄ™ buforze; podobnie w przypadku krótkich sekwencji instrukcji if ... then ... else ... rozkazy wskazywane przez adresy instrukcji skokowych również znajdować siÄ™ bÄ™dÄ… w buforze. Kodowanie programów bez użycia skoków f& współczesne procesory umożliwiajÄ… równolegÅ‚e wykonywanie kilku instrukcji (ang. ILP instruction level parallelism) w jednym cyklu zegarowym; dwa istotne czynniki ograniczajÄ… równolegÅ‚ość wykonywania: " zle przewidziane rozgaÅ‚Ä™zienia (skoki); " relatywnie wysokie opóznienie zwiÄ…zane z Å‚adowaniem danych z pamiÄ™ci; f& w wielu współczesnych procesorach algorytmy przewidywania rozgaÅ‚Ä™zieÅ„ majÄ… na celu okreÅ›lenie czy pewien konkretny skok w programie zostanie wykonany; trafne przewidywanie rozgaÅ‚Ä™zieÅ„ pozwala procesorowi okreÅ›lić wczeÅ›niej przepÅ‚yw sterowania, i pobierać te instrukcje, które znajdujÄ… siÄ™ w Å›cieżce wykonania; f& w praktyce dokÅ‚adne przewidywanie rozgaÅ‚Ä™zieÅ„ może być trudne, i czÄ™sto wymaga pewnych form analizy sprzężenia zwrotnego, by staÅ‚a siÄ™ efektywna; bÅ‚Ä™dne przewidywanie powoduje opóznienia siÄ™gajÄ…ce do 10 cykli zegara; f& niezależnie od problemów zwiÄ…zanych ze zle przewidzianymi rozgaÅ‚Ä™zieniami, obecność rozkazów sterujÄ…cych (skokowych) może ograniczać możliwoÅ›ci optymalizacji kodu poprzez przestawianie instrukcji; f& w ostatnich latach skupiono wiÄ™c uwagÄ™ na sposobach kodowania, w których nie używa siÄ™ (lub ogranicza) rozkazów skoku warunkowego; omawiany problem wyjaÅ›nimy na przykÅ‚adzie; f& przypuśćmy, że w rejestrach ESI i EDI znajdujÄ… siÄ™ dwie 32-bitowe liczby caÅ‚kowite bez znaku, a zadanie polega na wyÅ›wietleniu na ekranie wiÄ™kszej z tych liczb; konwencjonalne rozwiÄ…zanie mogÅ‚oby wyglÄ…dać tak: mov eax, esi cmp esi, edi jae dalej mov eax, edi dalej: call wyswietl32 ; wyÅ›wietlanie zawartoÅ›ci EAX f& poszukiwanÄ… wartość można wyznaczyć także w inny sposób; przyjmijmy, że 32-bitowa zmienna b może przyjmować wartoÅ›ci 00...000 (false) albo 11...111 (true); algorytm obliczeÅ„, w którym nie używa siÄ™ skoków, można zapisać w postaci: b = ESI > EDI wynik = ESI & b + EDI & (~ b) print (wynik) gdzie symbole & i ~ oznaczajÄ…: & bitowy iloczyn logiczny ~ negacja bitowa f& podany algorytm implementuje poniższa sekwencja rozkazów: mov edx, 0 ; zmienna b cmp esi, edi setg dl ; wpisanie 1 do DL, jeÅ›li ESI > EDI neg edx ; zmiana znaku liczby kodowanej w U2 ; jeÅ›li liczba w ESI byÅ‚a wiÄ™ksza od liczby w EDI, to w EDX ; (zmienna b) bÄ™dÄ… same jedynki, w przeciwnym razie same zera and esi, edx not edx and edi, edx or esi, edi mov eax, esi call wyswietl32 ; wyÅ›wietlanie zawartoÅ›ci EAX f& warto dodać, że rozkaz SETG można zastÄ…pić kilkoma typowymi rozkazami, które wykonujÄ… operacje bitowe i arytmetyczne na znacznikach CF i ZF odczytanych za poÅ›rednictwem stosu (rozkaz PUSHF); f& przedstawiona tu metoda programowania, nazywana metodÄ… predykatowÄ… (ang. predication), jest wspomagana sprzÄ™towo w najnowszych typach procesorów, m.in. w 64- bitowym procesorze Itanium. Metoda predykatowa w procesorze Itanium f& w procesorach IA-64 udostÄ™pniono mechanizm predykatowego wykonywania (ang. predicated execution) instrukcji, który pozwala na caÅ‚kowite wyeliminowanie rozgaÅ‚Ä™zieÅ„ w programie; wymaga to jednak stosowania innej techniki programowania, którÄ… ilustruje poniższy przykÅ‚ad if (x > 5) printf("x > 5\n"); else printf("x <= 5\n"); f& najpierw, na podstawie porównania zmiennej x i liczby 5 obliczane sÄ… wartoÅ›ci zmiennych boolowskich b1 i b2; jeÅ›li x > 5, to b1 przyjmuje wartość true, w przeciwnym razie false; analogicznie jeÅ›li x > 5, to b2 przyjmuje wartość false, a przeciwnym razie true; b1, b2 = cmp.gt x,5 // obliczenie zmiennych // boolowskich b1 i b2 na // podstawie porównania x i 5 (b1) call printf "x > 5\n" // instrukcja jest // wykon. gdy b1=true (b2) call printf "x <= 5\n" // instrukcja jest // wykon. gdy b2=true f& instrukcje call wykonywane sÄ… tylko wówczas, jeÅ›li wyrażenie podane w nawiasie ma wartość true; zatem jeÅ›li zmienna b1 ma wartość true, to wykonywana jest instrukcja call, która wyÅ›wietla tekst "x > 5\n"; analogicznie jeÅ›li zmienna b2 ma wartość true, to wykonywana jest druga instrukcja call; f& zatem, używanie wartoÅ›ci boolowskich (predykatów) pozwala przeksztaÅ‚cić instrukcje if- then-else na kod bez rozgaÅ‚Ä™zieÅ„; transformacja ta nazywana jest if-konwersjÄ… (ang. if- conversion); f& procesory IA-64 posiadajÄ… rozbudowane mechanizmy wykonywania kodu predykatowego; istniejÄ… liczne instrukcje porównania, które pozwalajÄ… na tworzenie wartoÅ›ci logicznych; prawie wszystkie instrukcje IA-64 mogÄ… wÅ‚Ä…czane i wyÅ‚Ä…czane poprzez predykaty z odpowiednimi wartoÅ›ciami; f& nadmierne stosowanie omawianej techniki może prowadzić do zwiÄ™kszenia dÅ‚ugoÅ›ci kodu technikÄ™ tÄ™ trzeba wprowadzać ostrożnie. Optymalizacja kodu programu f& w zastosowaniach wymagajÄ…cych bardzo dużej prÄ™dkoÅ›ci przetwarzania (np. sterowanie poruszajÄ…cymi siÄ™ obiektami, poszukiwania w wielkich bazach danych) niektóre, krytyczne fragmenty programu koduje siÄ™ na poziomie rozkazów procesora; w takich przypadkach wskazane jest umieszczenie rozkazów w takiej kolejnoÅ›ci, aby wyeliminować konflikty wynikajÄ…ce ze specyfiki przetwarzania potokowego; f& dostÄ™pna jest dość obszerna literatura poÅ›wiÄ™cona temu zagadnieniu, ale proponowane rozwiÄ…zania sÄ… Å›ciÅ›le uzależnione od architektury używanego procesora; f& spoÅ›ród najczęściej podawanych zaleceÅ„ można podać: obliczanie wartoÅ›ci modyfikatora z wyprzedzeniem, unikanie modyfikacji adresowej z użyciem dwóch modyfikatorów czy też współczynnika skali, f& przykÅ‚ad: obliczenie wartoÅ›ci wyrażenia J := K + M + N + P; rozwiÄ…zanie podane w prawej kolumnie realizowane jest przez dwie jednostki wykonawcze procesora, a zatem wymaga mniej cykli procesora. mov ax, K mov bx, K add ax, M mov ax, M add ax, N add bx, N add ax, P add ax, P mov J, ax add ax, bx mov J, ax Problemy dostÄ™pu do pamiÄ™ci f& dostÄ™p do pamiÄ™ci we współczesnych komputerach wymaga relatywnie dÅ‚ugiego czasu w porównaniu z czasem dekodowania i wykonywania instrukcji; znaczna poprawa w tym zakresie nastÄ…piÅ‚a po wprowadzeniu pamiÄ™ci podrÄ™cznej w procesorze, ale także i w tym przypadku potrzeba kilku cykli procesora; f& jednym ze sposobów rozwiÄ…zania tego problemu jest odczytywanie danych z pamiÄ™ci z wyprzedzeniem; w trakcie analizy poniższego kodu można przyjąć zaÅ‚ożenie, że wykonanie instrukcji zajmuje 1 cykl, ale zaÅ‚adowanie danych z pamiÄ™ci podrÄ™cznej zajmuje 3 cykle; zatem wykonanie podanego niżej kodu zajmuje 11 cykli; r16 = call rand ( ) add r16 = r16, 2 mul r16 = r16, 4 st8 [r16] = 2 ld8 r17 = addr("x") // wyznaczanie adresu "x" ld8 r18 = [r17] // Å‚adowanie zmiennej x z pamiÄ™ci add r18 = r18, 1 st8 [r17] = r18 // zapisywanie x do pamiÄ™ci f& w trakcie wykonywania powyższych instrukcji wystÄ™puje oczekiwanie procesora przez 3 cykle; niżej podany kod wymaga jednak tylko 8 cykli; r16 = call rand ( ) ld8 r17 = addr("x") // wyznaczanie adresu "x" ld8 r18 = [r17] // Å‚adowanie zmiennej x z pamiÄ™ci add r16 = r16, 2 mul r16 = r16, 4 st8 [r16] = 2 add r18 = r18, 1 st8 [r17] = r18 // zapisywanie x do pamiÄ™ci