Architektura Komputerów/Wykład 7: Działanie potokowej jednostki wykonawczej


Plan wykładu






Potokowa jednostka wykonawcza - MIPS R3000






Potok MIPS R3000



Potok R3000 składa się z pięciu stopni.


Stopień IF pobiera instrukcje z hierarchii pamięci instrukcji (zewnętrznej w stosunku do procesora).


Stopień RD odczytuje zawartości rejestrów źródłowych z zestawu rejestrów procesora.


Stopień ALU wykonuje operację arytmetyczną i ew. skok.


Stopień MEM dokonuje wymiany danych z hierarchią pamięci danych.


Stopień WB zapisuje wynik operacji arytmetycznej lub daną odczytaną z pamięci do rejestru.




Budowa i działanie potoku MIPS R3000





  • Na końcu każdego stopnia (oprócz WB) jest umieszczony rejestr typu D
  • Aktualizacja PC i rejestrów uniwersalnych następuje w połowie cyklu zegara
    • pobranie instrukcji zaczyna się w połowie cyklu
    • zapis wyniku do rejestru następuje w połowie cyklu
    • odczyt danej z rejestru następuje w drugiej połowie fazy RD
  • Wszystkie sygnały potrzebne do dokończenia wykonania instrukcji są zapamiętywane w rejestrach i przekazywane do kolejnych stopni potoku, w tym. m in.:
    • sygnały sterujące
    • numer rejestru docelowego

Wykonanie sekwencji instrukcji w potoku



Diagram ilustruje wykonanie instrukcji przez potok procesora MIPS R3000. W każdym cyklu procesor rozpoczyna wykonanie nowej instrukcji i kończy wykonanie wcześniejszej instrukcji.


W każdym cyklu w potoku przebywa 5 instrukcji w różnych fazach wykonania.



Synchronizacja potoku





  • Rozpatrzmy wykonanie sekwencji instrukcji:
  • addu $4, $3, $2
  • addu $6, $5, $4
    • druga instrukcja korzysta z argumentu źródłowego w rejestrze $4
    • rejestr ten jest rejestrem docelowym pierwszej instrukcji
    • instrukcja zapisuje wynik w stopniu WB
    • odczyt argumentów następuje w stopniu RD
    • kiedy druga instrukcja znajduje się w stopniu RD, pierwsza przebywa w stopniu ALU
    • zapis wyniku przez pierwszą instrukcję nastąpi w dwa cykle później
  • Problem: jaką wartość $4 pobierze druga instrukcja?
    • byłaby to wartość nie zaktualizowana przez pierwszą instrukcję
    • nie ma pewności, czy wykonanie programu użytkowego nie zostanie przerwane pomiędzy 1. i 2. instrukcją, a następnie wznowione
      • w takiej sytuacji pierwsza instrukcja zakończy się i zapisze wynik

Podczas wykonania przedstawionej sekwencji instrukcji w potoku, druga instrukcja, znajdując się w stopniu RD odczytuje zawartość rejestru, który pierwsza instrukcja zaktualizuje w stopniu WB, a więc w trzy cykle później.


Podczas wykonania programu użytkowego może się zdarzyć, że wykonanie strumienia instrukcji zostanie przerwane, a następnie podjęte na nowo po jakimś czasie. W międzyczasie procesor będzie wykonywał inne sekwencje instrukcji, należące do procedur systemowych lub innego procesu użytkownika. W takiej sytuacji. przed przełączeniem kontekstu procesor zakończy wykonanie instrukcji pierwszej, nie rozpoczynając wykonania drugiej (a właściwie anulując efekty jej wykonania).


Po powrocie do przerwanego procesu rozpocznie się wykonanie go od drugiej instrukcji. W takiej sytuacji druga instrukcja pobierze z rejestru wynik zapisany przez pierwszą instrukcję.



Hazard R-A-W




  • Nie da się jednoznacznie określić, jaką wartość rejestru pobierze druga instrukcja
    • jeżeli pomiędzy pierwszą i drugą instrukcją nastąpi np. przełączenie procesów, druga instrukcja pobierze wartość zaktualizowaną przez pierwszą
  • Zachowanie programu jest niedeterministyczne - sytuację taką nazywamy HAZARDEM
  • Ponieważ hazard wynika z umieszczenie w programie instrukcji odczytującej rejestr po instrukcji zapisującej rejestr ten typ hazardu jest określany jako „odczyt po zapisie" (read-after-write albo RAW hazard)
  • Konieczne jest wprowadzenie determinizmu w zachowaniu procesora, czyli usunięcie hazardu

Ponieważ nie wiadomo, czy wykonanie programu zostanie zawieszone, a następnie wznowione pomiędzy instrukcją pierwszą i drugą – nie można jednoznacznie określić, jaką wartość rejestru $4 pobierze druga instrukcja. Sytuacja taka jest nazywana hazardem.


Program musi być wykonywany deterministycznie – niezbędne jest usunięcie wszelkich niedeterminizmów i zagwarantowanie jednoznaczności wykonania.



Usuwanie hazardu R-A-W




  • Metoda „administracyjna"
    • skutek wykonania instrukcji korzystającej z danego rejestru jako źródłowego wcześniej niż w 3 instrukcje po instrukcji zapisującej rejestr zostaje opisany w dokumentacji procesora jako nieokreślony
      • programiście nie wolno użyć takiej sekwencji instrukcji
  • wada: b. często trzeba w programie wstawiać instrukcje puste

Najprostszą metodą usunięcia hazardu RAW jest uznanie sekwencji instrukcji powodującej hazard za nielegalną i niedozwoloną. Stosowny zapis w dokumentacji powinien określać minimalny odstęp pomiędzy instrukcją wyliczającą wynik i instrukcją korzystającą z tego wyniku jako z argumentu źródłowego.


Metoda ta jest niepraktyczna, gdyż na ogół instrukcje programów tworzą sekwencje – łańcuchy, w których kolejne instrukcje korzystają z wyników instrukcji poprzedzających. W praktyce programiści musieliby więc umieszczać w programach dużo instrukcji pustych dla zapewnienia odpowiednich odstępów pomiędzy instrukcjami generującymi hazardy.





  • Wstrzymywanie potoku po wykryciu hazardu
    • układ kombinacyjny porównuje numery rejestrów źródłowych instrukcji w stopniu RD z numerami rejestrów docelowych instrukcji w stopniu ALU i MEM
    • w przypadku wykrycia zgodności, instrukcja zostaje zatrzymana w stopniu RD
      • stopnie IF i RD "stoją"
      • pozostałe stopnie pracują normalnie, ze stopnia RD do ALU jest "wstrzykiwana" instrukcja pusta
    • program wykonuje się poprawnie, bez konieczności dodawania instrukcji pustych
    • zależności między instrukcjami powodują opóźnienia
      • w programach często występują sekwencje instrukcji zależnych

Hazard w potoku można stosunkowo łatwo wykryć, umieszczając w stopniu RD komparatory, porównujące numery rejestrów źródłowych odczytywanych przez stopień RD z numerami rejestrów docelowych instrukcji przebywających w stopniach ALU i MEM. (Przypomnijmy, że stopień RD może oczytać rejestr zapisywany w tym samym cyklu w stopniu WB.)


W razie wykrycia hazardu, instrukcja odczytu zostaje zatrzymana w stopniu RD, a do stopnia ALU zostaje wstrzyknięta instrukcja pusta. Instrukcja odczytu opuści stopień RD, kiedy zniknie ostrzeżenie o hazardzie, czyli w chwili, kiedy instrukcja zapisu znajdzie się w stopniu WB.



Działanie potoku MIPS R3000 - przypomnienie





  • Zapis rejestru następuje w połowie cyklu, który instrukcja spędza w stopniu WB
  • Odczyt rejestru źródłowego rozpoczyna się w połowie cyklu, który instrukcja spędza w stopniu RD
  • Dana zapisana przez instrukcję znajdującą się w stopniu WB może być odczytana w tym samym cyklu przez instrukcję znajdującą się w stopniu RD
  • Wystarczą dwa cykle odstępu pomiędzy parą instrukcji zależnych


Usuwanie hazardu R-A-W (3) - obejście




  • Wynik operacji arytmetycznej jest dostępny już w stopniu ALU
    • wartość wyniku instrukcji jest gotowa, gdy następna instrukcja przebywa w stopniu RD
  • Obejścia - to szyny poprowadzone ze stopni ALU i MEM do stopnia RD
    • po obejściu jest przesyłany numer rejestru docelowego i wynik instrukcji
  • Logika odczytu w stopniu RD:
    • numer rejestru źródłowego jest porównywany z numerami rejestrów na obejściach
    • priorytety obejście z ALU, obejście z MEM, fizyczny rejestr procesora
  • Obejście ze stopnia WB jest zbędne
  • Obejścia eliminują hazard RAW bez wprowadzania opóźnień!
    • w R3000 zastosowano obejścia wg. opisanego schematu

Najbardziej efektywna metoda usuwania hazardu RAW wymaga nieco większych nakładów sprzętowych, w postaci rozbudowy stopnia odczytu i przeprowadzenia dodatkowych ścieżek danych ze stopni ALU i MEM do stopnia RD.


Na ścieżkach tych są przesyłane numery rejestrów docelowych oraz wartości danych z wyjść stopni. W przypadku operacji arytmetycznych będą to gotowe wyniki, które później zostaną zapisane do rejestrów docelowych.


W ten sposób w stopniu RD można pobrać jako argumenty źródłowe wartości rejestrów, zanim zostaną one zapisane do rejestrów procesora.



Obejście - działanie




W przedstawionym przykładzie obejścia ze stopni ALU i MEM zawierają wartości, które w przyszłości zostaną zapisane do rejestrów $5 i $4. Instrukcja przebywająca w stopniu RD specyfikuje jako argumenty źródłowe właśnie te rejestry.


Logika stopnia RD spowoduje, że wartości argumentów zostaną pobrane nie z rejestrów $4 i $5, a z obejść.



Opóźnienie wynikające z dostępu do pamięci





  • Zakładamy, że procesor został wyposażony w obejścia eliminujące hazard RAW
  • Rozważmy sekwencję instrukcji:
        Iw $4, ....
        add $6, $5, $4
    • tym razem hazard RAW wynika z odwołania do pamięci
    • dana odczytana z pamięci będzie dostępna w stopniu MEM
    • obejścia redukują opóźnienie, ale go nie eliminują!
      • dana ze stopnia MEM może być przekazana obejściem
      • kiedy instrukcja używająca danej jest w stopniu RD, instrukcja ładowania jest dopiero w stopniu ALU
  • Problem ten jest nazywany opóźnieniem pomiędzy załadowaniem danej z pamięci i jej użyciem (load-use pen alty)

Przedstawiony problem jest szczególnym przypadkiem hazardu RAW. Tym razem instrukcja zapisująca wynik jest instrukcją ładowania danej z pamięci.


Kiedy instrukcja odczytująca rejestr $4 znajduje się w stopniu RD, instrukcja zapisująca rejestr jest w stopniu ALU. Dostęp do pamięci nastąpi w stopniu MEM. Obejście ze stopnia ALU nie może więc zawierać wyniku instrukcji ładowania.


Wynik ten będzie dostępny na obejściu ze stopnia MEM, kiedy instrukcja ładowania znajdzie się w stopniu MEM. Nie ma możliwości przyspieszenia tej operacji, a obejścia nie są w stanie usunąć hazardu.





  • Hazard wynikający z opóźnienia nie może zostać wyeliminowany bez opóźnień
  • W MIPS R3000 instrukcja korzystająca z danej pobranej z pamięci nie może być umieszczona bezpośrednio za instrukcją ładowania
    • zastosowano metodę administracyjną
    • w późniejszych wersjach MIPS, w tym w architekturze MIPS32 hazard jest usuwany sprzętowo, poprzez wstrzymanie początku potoku

Eliminacja hazardu wymaga wprowadzenia opóźnienia pomiędzy instrukcją ładowania i instrukcją korzystającą z załadowanych danych. Można to zrobić na dwa sposoby – poprzez zaznaczenie takiej konieczności w dokumentacji lub przy użyciu opisanego wcześniej mechanizmu wykrywania hazardu, powodującego wstrzykiwanie do potoku instrukcji pustych.


W obu przypadkach w pracy procesora pojawi się opóźnienie.


W MIPS R3000 zastosowano metodę administracyjną – programiście nie wolno użyć danej ładowanej z pamięci w instrukcji następującej bezpośrednio po instrukcji ładowania. W nowszych implementacjach architektury MIPS, w tym w wersji architektury oznaczonej jako MIPS32, usunięto to zastrzeżenie, a eliminację hazardu dba sprzęt.



Instrukcje skoków w potoku




  • Określenie warunku skoku i obliczenie adresu docelowego następuje w stopniu ALU, w połowie cyklu
  • W tym czasie w stopniu RD przebywa już instrukcja zapisana w programie za instrukcją skoku
  • Instrukcja skoku może mieć wpływ dopiero na pobranie kolejnej instrukcji
    • instrukcja pobrana po instrukcji skoku może zostać anulowana, ale zajmuje czas procesora
  • Opóźnienie skoków w architekturze potokowej wynika z odległości pomiędzy stopniem, w którym następuje skok (ALU) i stopniem pobrania instrukcji

Podobny problem występuje w odniesieniu do instrukcji skoków. Skok jest realizowany w stopniu ALU, kiedy instrukcja następująca bezpośrednio po instrukcji skoku znajduje się już w stopniu RD. Zmiana PC dokonana w stopniu ALU wpływa natychmiast na działanie stopnia IF, który pobiera instrukcję spod adresu docelowego skoku. W potoku znalazła się jednak już jedna instrukcja za instrukcją skoku.


Instrukcja ta może zostać anulowana (zmieniona w instrukcję pustą), ale nie ma możliwości odzyskania cyklu straconego na jej pobranie i wykonanie. Struktura potoku wprowadza opóźnienie w wykonaniu instrukcji skoku. W przypadku R3000 opóźnienie to wynosi jeden cykl.



Redukcja opóźnienia skoków w potoku





  • Technika redukcji opóźnienia używana w krótkich potokach polega na zredefiniowaniu instrukcji skoku
  • Skok opóźniony (delayed branch) - „wykonaj instrukcję umieszczoną za skokiem i skocz"
  • Za skokiem można umieścić dowolną instrukcję, która ma być wykonana przed skokiem i od której nie zależy wykonanie skoku
  • Miejsce za instrukcją skoku, zawierające instrukcje wykonywane niezależnie od realizacji skoku, nazywa się slotem opóźnienia (delay slot)
  • Przy slocie opóźnienia o rozmiarze jednej instrukcji prawdopodobieństwo wypełnienia slotu przez kompilator użyteczną instrukcją jest rzędu 90%
    • w razie braku takiej instrukcji w slocie umieszcza się instrukcję pustą

We wczesnych procesorach RISCowych stosowano prosty sposób redukcji opóźnienia skoków. Polega on na zmianie definicji instrukcji skoku ze „skocz” na „wykonaj jedną instrukcję, a potem skocz”. W ten sposób działanie procesora potokowego polegające na pobieraniu „zbędnej” instrukcji zostaje usankcjonowane, a wykonanie instrukcji następującej za instrukcją skoku staje się normą.


Z badań statystycznych wynika, że w większości przypadków daje się znaleźć w programie przed instrukcją skoku taką instrukcję, której wykonanie nie wpływa na wykonanie skoku. Instrukcja taka może zostać przez programistę lub kompilator przesunięta za instrukcję skoku.



Wydajność potoku





  • Teoretyczna wydajność potoku - jeden cykl na instrukcję
  • Czynniki powodujące opóźnienia:
    • wewnątrz potoku:
      • hazardy usuwane inaczej niż przez obejścia
      • ładowanie danych z pamięci
      • skoki
    • na zewnątrz potoku
      • dostępy do hierarchii pamięci, których relizacja wymaga > 1 cyklu
  • Praktyczna wydajność osiągana przez procesory potokowe - ok. 1.2 cyklu na instrukcję

W idealnym przypadku procesor potokowy powinien pracować bez zatrzymań, zaczynając i kończąc wykonanie kolejnej instrukcji w każdym cyklu.


W rzeczywistości opisane wcześniej opóźnienia wynikające z konieczności usuwania hazardów w potoku oraz opóźnienia w dostępach do hierarchii pamięci powstające poza potokiem powodują, że rzeczywista szybkość wykonywania instrukcji w procesorach o krótkich potokach wynosi przeciętnie około 1.2 cyklu procesora na instrukcję.



Przyśpieszenie potoku




  • Przy wzroście częstotliwości pracy odwołania do pamięci nie mogą być wykonane w jednym cyklu
    • każde odwołanie powoduje wstrzymanie potoku, przez co potok działa wolniej, niż przy mniejszej częstotliwości
  • Złożoność niektórych stopni potoku uniemożliwia podniesienie częstotliwości pracy
  • Rozwiązaniem jest przebudowanie potoku poprzez zwiększenie liczby stopni i zmianę szczegółów współpracy z pamięcią
  • Potok wydłużony, o długości powyżej 6 stopni jest nazywany superpotokiem

Wraz z ulepszaniem technologii półprzewodnikowej wzrasta dopuszczalna częstotliwość pracy układów. Przy skracaniu cyklu pracy procesora potokowego można zaobserwować, że powyżej pewnej częstotliwości granicznej przestają działać niektóre bardziej złożone stopnie, a ponadto dostęp do hierarchii pamięci w jednym cyklu staje się niemożliwy.


Każda architektura potoku, wraz z otoczeniem (hierarchią pamięci) ma określoną częstotliwość graniczną, powyżej której albo procesor przestaje działać, albo stopnie wymiany z pamięcią muszą czekać dodatkowy cykl na zakończenie operacji. W efekcie przyspieszenie zegara jest albo niemożliwe, albo przynosi spadek wydajności zamiast jej wzrostu.


Dalsze przyspieszanie wymaga zmiany struktury potoku poprzez zwiększenie liczby stopni. Uzyskuje się w ten sposób architekturę zwaną superpotokiem.



Budowa superpotoku MIPS R4000



MIPS R4000 posiada potok wydłużony do ośmiu stopni. Dwie najistotniejsze zmiany w stosunku do R3000 – to rozbicie stopni współpracujących z hierarchiami pamięci na dwa stopnie w przypadku pobrania instrukcji i trzy stopnie dla odwołań do danych.


Superpotok - MISP R4000




  • R4000 - rok 1989 - pierwszy mikroprocesor 64-bitowy
  • Zgodny programowo na poziomie binarnym z R3000
  • Superpotok 8-stopniowy
    • IF - Instruction First - początek pobrania instrukcji
    • IS - Instruction Second - zakończenie pobrania instrukcji
    • RD - Read - odczyt argumentów
    • EX - Execute - odpowiednik ALU w R3000
    • DF - Data First - początek odwołania do danych
    • DS - Data Second - zakończenie transakcji z pamięcią danych
    • DTC - Data Tag Check - finalizacja odwołania
    • WB - Write Back - zapis wyniku do rejestru


Współpraca z pamięcią



  • Odwołania do pamięci rozbite na dwie fazy
  • Pamięć ma budowę potokową
    • dostęp następuje w dwóch cyklach zegara
    • taki podział cyklu dostępu jest naturalny z punktu widzenia budowy wewnętrznej pamięci
    • równocześnie wykonywane są dwa dostępy do pamięci

Rozbicie stopni odwołań do pamięci oznacza, że nie tylko procesor, ale również pamięć wykonuje każdy dostęp w dwóch cyklach zegara. Wymaga to specjalnej konstrukcji pamięci, umożliwiającej potokowy dostęp. Taka modyfikacja budowy pamięci jest dość naturalna i polega na wprowadzeniu dodatkowego rejestru na wyjściach matrycy pamięci. Pamięć potokowa wykonuje w każdej chwili dwa dostępy – drugą połowę pierwszego i pierwszą połowę drugiego dostępu.


Opóźnienia i synchronizacja superpotoku



  • Topologia superpotoku jest taka sama, jak potoku
    • brak nowych problemów synchronizacyjnych
  • Większa liczba stopni powoduje zwiększenie odległości, z których wynikają hazardy i opóźnienia
    • opóźnienia mierzone w cyklach są większe, niż w przypadku krótkiego potoku
    • potrzebna większa liczba obejść
  • Opóźnienie pomiędzy załadowaniem danej i jej użyciem oraz opóźnienie skoków- znacznie większe, niż w krótkim potoku

Ponieważ ogólny kształt superpotoku nie różni się od pooku, w superpotoku występują takie same problemy synchronizacyjne i opóźnienia, jak w krótkim potoku.


Większa liczba stopni i związane z tym większe odległości pomiędzy stopniami implikują konieczność wyposażenie superpotoku w większą liczbę obejść w celu likwidacji hazardu RAW. Również nieusuwalne opóźnienia ładowania danych i skoków mierzone w cyklach zegara są w tym przypadku większe.



Opóźnienie danych w superpotokach




  • Przy zastosowaniu obejść opóźnienie wynosi 3 cykle 
  • Nie jest ono szczególnie krytyczne
    • procesory potokowe mają zwykle wiele rejestrów - skalarne obiekty lokalne procedury są umieszczone w rejestrach
  • Odwołania do pamięci:
    • przeładowanie rejestrów w epilogu procedury-zawartość rejestrów potrzebna po wykonaniu kilku instrukcji
    • dostęp do struktur danych (np. tablic) - dane często potrzebne natychmiast - opóźnienie spowalnia wykonanie programu
  • Wyższa częstotliwość pracy powoduje, że opóźnienia występujące na zewnątrz potoku (wyrażone w cyklach) są większe

Wskutek większej odległości pomiędzy stopniem finalizującym odwołanie do danych (DTC) i stopniem odczytu argumentów, opóźnienie danych jest 3-krotnie większe, niż w krótkim potoku. Ponieważ z koncepcji RISC wynika, że dane lokalne znajdują się na ogół w rejestrach procesora, opóźnienie danych będzie krytyczne głównie przy odwołaniach do struktur danych w pamięci (np. operacje na tablicach).


Sekwencja ładowania rejestrów będzie występowała również na końcu procedur, w tym przypadku jednak kilka instrukcji wykonywanych w epilogu po ładowaniu rejestrów skutecznie zamaskuje opóźnienie.



Opóźnienie skoków w superpotokach



  • Rozmiar slotu opóźnienia w superpotokach jest większy niż w krótkich potokach
    • dla MIPS R4000 - 2
  • Prawdopodobieństwo wypełnienia całego slotu użytecznymi instrukcjami nie przekracza 20%
  • Skok opóźniony o dwa cykle nie jest dobrym rozwiązaniem problemu opóźnienia skoków
    • dodatkowo powstawałby problem zgodności wstecznej oprogramowania
  • W superpotokach nie powstałych na bazie wcześniejszych implementacji potokowych nie stosuje się skoków opóźnionych
  • Właściwą metodą redukcji opóźnienia w superpotokach jest przewidywanie skoków

Zwiększone opóźnienie skoków oznacza, że gdyby procesor superpotokowy miał używać instrukcji skoku opóźnionego, slot opóźnienia miałby rozmiar równy 2, czyli po instrukcji skoku procesor wykonywałby jeszcze dwie kolejne instrukcje. Takie rozwiązanie nie jest właściwe, gdyż prawdopodobieństwo znalezienia drugiej instrukcji, która mogłaby zostać przesunięta za skok jest niewielkie. Istotny byłby również brak zgodności programowej z wcześniejszymi realizacjami o krótszych potokach.


Z tych przyczyn nie używa się skoków opóźnionych z opóźnieniem większym od jednej instrukcji. Po każdej instrukcji skoku procesor R4000 musi anulować kolejną instrukcję, pobraną jako drugą po instrukcji skoku – pierwsza jest wykonywana, tak jak w R3000.


Architektury projektowane od razu z myślą o realizacji superpotokowej nie mają instrukcji skoku opóźnionego. Ze względu na duże opóźnienie skoków są one wyposażane w układy przyspieszające wykonanie skoków, omówione w oddzielnym module.



Wydajność superpotoków




  • Większe i częstsze opóźnienia powodują że wydajność wyrażona w cyklach na instrukcję jest gorsza, niż w przypadku krótkich potoków
    • typowa wydajność wynosi ok. 1.5 cyklu na instrukcję
  • Większa wartość CPI jest kompensowana wzrostem częstotliwości pracy
    • przyrost wydajności wynikający z wydłużenia potoku przy zachowaniu parametrów technologicznych wynosi ok. 50%


Potokowa realizacja procesora CISC



  • Architektura potokowa daje się łatwo zastosować, gdy:
    • sekwencja czynności jest stała dla wszystkich instrukcji
      • niektóre fazy niektórych instrukcji mogą być puste
    • instrukcje mają stałą długość i ich dekodowanie jest proste
    • instrukcja realizuje co najwyżej jedno odwołanie do pamięci danych
    • instrukcja ma jeden argument docelowy
  • Postulaty te nie są spełnione w modelach programowych CISC
  • Możliwości realizacji potokowej CISC
    • budowa potoku zdolnego do wykonywania instrukcji CISC
    • podział procesora na dwie części:
      • jednostka pobierająca instrukcje CISC i transkodująca je na prymitywy RISC
      • jednostka wykonawcza RISC

Modele programowe zgodne z założeniami koncepcji CISC nie pasują do koncepcji potoku, opracowanej równocześnie z koncepcją modelu programowego RISC. Aby procesory CISC mogły konkurować z procesorami RISC pod względem wydajności, konieczne stało się opracowanie potokowych realizacji procesorów CISC.


Są to możliwe dwa rodzaje realizacji. Pierwsza polega na skonstruowaniu potoku mogącego wykonywać instrukcje CISC. Druga zakłada, że po pobraniu instrukcje CISC będą translowane na sekwencje instrukcji podobnych do RISC, które będą następnie wykonywane w nieco zmodyfikowanym potoku.



Potok CISC




  • Potok przebudowany tak, by mógł wykonywać instrukcje CISC
    • kilka stopni na początku potoku zajmuje się pobieraniem instrukcji, dekodowaniem ich i wyliczaniem adresu efektywnego
      • instrukcje o zmiennych długościach wymagają skomplikowanego dekodera, niekiedy działające o w kilku cyklach
    • stopień odczytu argumentów pobiera argumenty z rejestrów lub pamięci
    • stopień wykonania o skomplikowanej budowie - wykonuje poszczególne instrukcje w różnej liczbie cykli
    • stopień zapisu zapisuje wynik do rejestru lub pamięci
      • skomplikowany interfejs pamięci z dwiema ścieżkami dostępu
  • Wydajność: średni czas wykonania instrukcji - około dwóch cykli
    • potok często zatrzymuje się
  • Przykłady - Intel i486. Motorola MC68040 - koniec lat 80-tych XX w.


Potok CISC - Intel i486



  • Fetch - pobranie instrukcji do bufora instrukcji
  • ID1 - wstępne dekodowanie, określanie długości
  • ID2 - obliczanie adresów 
  • EX - wymiana z pamięcią, odczyt rejestrów, operacja arytmetyczna lub logiczna 
    • stopień bardzo skomplikowany, w wielu instrukcjach wykonanie wielofazowe
  • WB - zapis wyniku do rejestrów

Pomimo, że potok CISC wygląda na rysunku podobnie do potoku RISC, należy zauważyć, że struktura poszczególnych stopni jest w tym przypadku dużo bardziej złożona, a poszczególne instrukcje mogą spędzać w niektórych stopniach po kilka, a nawet kilkadziesiąt cykli (dotyczy to zwłaszcza stopnia EX).


Procesor z transkodowaniem instrukcji



  • Jednostka transkodująca pobiera instrukcje CISC i zamienia je na sekwencje instrukcji podobnych do RISC
    • dla prostych instrukcji - translacja 1:1
    • nieco bardziej złożone instrukcje - zamieniane na 2..4 instrukcji RISC
    • instrukcje skomplikowane wykonywane jako procedury pobierane z pamięci ROM umieszczonej w procesorze
  • Jednostka wykonawcza wykonuje instrukcje typu RISC
    • różnice w stosunku do "czystego" RISC występujące w niektórych realizacjach:
      • instrukcje arytmetyczne z jednym odwołaniem do argumentu w pamięci
      • operacje stosowe (dwa argumenty docelowe, w tym SP)
  • Przykłady:
    • pierwsze realizacje - NexGen Nx586, IDT C6 (1995.. 97)
    • obecnie wszystkie procesory x86 działają na tej zasadzie


Procesor z transkodowaniem instrukcji - IDT C6



Procesor IDT C6 jest najprostszym przykładem procesora x86 z transkodowaniem instrukcji. Proste instrukcje CISC są zamieniane w jedną lub kilka instrukcji RISC w stopniu translatora. Bardziej skomplikowane instrukcje są translowane w RISCową instrukcję wywołania procedury z wbudowanej pamięci ROM. Zwykłe instrukcje trafiają wprost z kolejki instrukcji do pamięci. Wywołania procedur powodują uruchomienie pobierania instrukcji RISCowych z pamięci ROM.