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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

...


...


...


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.


...


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.


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ę.


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.


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.


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.


...


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.


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ść.


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.


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.


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.


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.


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ę.


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.


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.


...


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.


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.


...


...


...


...


...


...


...


...