Architektura Systemów Komputerowych Wykład 8: Procesory wielopotokowe, czyli superskalarne Dr inż. Marek Mika Państwowa Wyższa Szkoła Zawodowa im. Jana Amosa Komeńskiego W Lesznie
Plan Struktury i rodzaje procesorów superskalarnych Problemy synchronizacji i opóźnienia w procesorach superskalarnych
Od potoku do superskalara Idealna, teoretyczna wydajność procesorów potokowych wynosi 1CPI (cykl na instrukcję) Procesor nie może wykonać instrukcji w ułamku cyklu, ale może wykonać więcej niż jedną instrukcję w czasie jednego cyklu Procesor taki musi mieć więcej niż jeden potok wykonawczy Procesory wielopotokowe są nazywane procesorami superskalamymi lub superskalarami.
Struktura procesora superskalarnego Pobranie instrukcji Rozpoczynanie Potoki wykonawcze Porządkowanie Zapis zwrotny
Budowa i działanie procesora superskalarnego Pierwsze stopnie potoku pobierają i dekodują równocześnie kilka instrukcji Stopień inicjujący wykonanie instrukcji kieruje instrukcje do indywidualnych potoków wykonawczych każdy z potoków wykonuje po jednej instrukcji nie zawsze udaje się skierować instrukcję do każdego potoku Potoki wykonawcze wykonują pojedyncze instrukcje Stopień porządkujący decyduje o zatwierdzeniu wykonania instrukcji i modyfikacji widocznego programowo rejestru PC nieobecny w prostych superskalarach Stopień zapisu dokonuje nieodwracalnej modyfikacji kontekstu programowego (rejestrów i pamięci) w prostych superskalarach. bez stopnia porządkującego, stopnie zapisu są oddzielne dla poszczególnych potoków
Rodzaje procesorów superskalarnych Pseudosuperskalar np. Intel 860 rok 1989 Superskalar z kolejnym wykonaniem instrukcji (in-order execution) np. Intel Pentium 1993 Superskalar z kolejnym rozpoczynaniem i niekolejnym kończeniem instrukcji (in-order issue, out-of-order completion) Np.. Cyrix Cx 8x86 1994 Superskalar z niekolejnym wykonaniem instrukcji (out-oforder execution) np. Intel Pentium Pro 1995 niemal wszystkie współczesne procesory uniwersalne
Pseudosuperskalar Procesor pseudosuperskalarny nie ma możliwości decydowania o równoczesnym wykonaniu instrukcji decyzję podejmuje programista lub kompilator informacja o możliwości równoczesnego wykonania zawarta w kodzie operacyjnym instrukcji Przykład Intel 860 dwa potoki wykonawcze - stałopozycyjny i zmiennopozycyjny instrukcje o długości 32 bitów, pobierane parami równoczesne wykonanie obu instrukcji w parze jest możliwe, gdy: pierwsza jest stałopozycyjna, a druga zmiennopozycyjna instrukcja zmiennopozycyjna ma w kodzie operacyjnym ustawiony bit zezwolenia na równolegle wykonanie obie instrukcje wykonują się równocześnie nie występuje sytuacja, gdy jeden z potoków wykonawczych zatrzymuje się, a drugi kontynuuje pracę
Superskalar z kolejnym wykonaniem instrukcji Procesor decyduje o możliwości równoległego wykonania instrukcji wykonanie jest możliwe, gdy instrukcje nie zależą od instrukcji poprzedzających kierowanych do wykonania w tym samym cyklu liczba instrukcji kierowanych do wykonania zależy ponadto od liczby i rodzajów dostępnych potoków Poszczególne potoki mogą być identyczne, podobne bądź różne jeden potok wykonuje wszystkie instrukcje, drugi tylko prostsze (Intel Pentium) oddzielne potoki dla różnych instrukcji, np. stałopozycyjnych, zmiennopozycyjnych, wymiany z pamięcią, skoków (np. SuperSPARC I, Alpha 21064) Potoki pracują synchronicznie wstrzymanie jednego powoduje równoczesne wstrzymanie wszystkich
Superskalar z kolejnym wykonaniem instrukcji c.d. Kierowanie instrukcji do wykonania po równoległym pobraniu grupy kilku (2 lub 4) instrukcji są one kierowane do wykonania równocześnie lub jedna po drugiej, do czasu rozpoczęcia wykonania wszystkich instrukcji z grupy; następnie rozpoczyna się kierowanie do wykonania instrukcji z następnej grupy np. Alpha 21064 wydajność zależy od ustawienia instrukcji w grupy łatwa konstrukcja stopnia szeregującego tzw. okno instrukcji w każdym cyklu stopień szeregujący ma do dyspozycji kilka instrukcji, z których co najmniej pierwsze kieruje do wykonania; w następnym cyklu następuje dobieranie instrukcji tak, że w każdym cyklu można potencjalnie rozpocząć taką samą liczbę instrukcji np. Intel Pentium (P5), SuperSPARC I większa wydajność, opłacona komplikacją stopnia szeregującego
Superskalar z kolejnym rozpoczynaniem i niekolejnym kończeniem Instrukcje są pobierane i dekodowane po kilka sztuk w kolejności programowej Stopień szeregujący rozpoczyna wykonanie w kolejności programowej Po skierowaniu instrukcji do potoków wstrzymanie jednego potoku nie powoduje wstrzymania pozostałych instrukcje mogą być kończone w innej kolejności od programowej Wzrost wydajność dzięki lepszemu wykorzystaniu potoków Przykład: Cyrix 6x86 (ok. 1995r) wydajność o ok 30% wyższa od Intel P5 przy podobnej strukturze Problem: zmiana kolejności kończenia instrukcji może wprowadzać problemy synchronizacyjne (omówione póżniej)
Superskalar z niekolejnym wykonaniem instrukcji Zdekodowane instrukcje są gromadzone w stopniu szeregującym Skierowanie instrukcji do wykonania zachodzi wtedy, gdy są gotowe argumenty źródłowe wykonanie może być rozpoczynane w kolejności innej niż programowa Dwa rozwiązania szeregowania centralny bufor instrukcji przed rozejściem na indywidualne potoki kosztowny w realizacji zapewnia równe obciążenie przy kilku identycznych potokach. np. Intel P6, AMD K6 bufory w pierwszych stopniach potoków wykonawczych (tzw. stacje rezerwacyjne algorytm Tomasulo) proste w realizacji, ale powoduje suboptymalne wykorzystanie potoków np. AMD K5
Superskalar z niekolejnym wykonaniem instrukcji c.d. Procesor w każdej chwili musi mieć ważną wartość PC, i tym samym instrukcję, do której program został wykonany instrukcję uznaje się za ostatecznie wykonaną, jeśli również wszystkie instrukcje ją poprzedzające zostały wykonane instrukcja po przejściu przez potoki wykonawcze trafia do stopnia RETIRE, gdzie oczekuje na zakończenie instrukcji poprzedzających przed ostatecznym zakończeniem wykonania instrukcja nie może w sposób trwały modyfikować kontekstu procesora ani pamięci Dwa ostatnie stopnie superskalara oczekiwanie na zakończenie wykonania instrukcji poprzedzających nieodwracalna modyfikacja kontekstu Niemal wszystkie współczesne procesory do komputerów uniwersalnych wykonują instrukcje nie w kolejności np. AMD K8, Intel Pentium 4, Intel Core
Synchronizacja superskalara ze zmianą kolejności instrukcji (1) Rozpatrzmy wykonanie sekwencji instrukcji addu $4,$3,$2 addu $2,$5,$4 pierwsza instrukcja korzysta z argumentu źródłowego w rejestrze $2 rejestr ten jest rejestrem docelowym drugiej instrukcji Problem: jaką wartość $2 pobierze pierwsza instrukcja? zakończenie wykonania drugiej instrukcji przed odczytem rejestru $2 przez pierwszą instrukcję spowoduje błędne wykonanie pierwszej instrukcji Niejednoznaczność ta jest nazywana hazardem W-A-R (zapis po odczycie) procesor musi zagwarantować poprawne wykonanie takiej sekwencji instrukcji
Synchronizacja superskalara ze zmianą kolejności instrukcji (2) Rozpatrzmy wykonanie sekwencji instrukcji addu $4,$3,$2 addu $4,$8,$9 addu $2,$5,$4 trzecia instrukcja korzysta z argumentu źródłowego w rejestrze $4 rejestr ten jest rejestrem docelowym pierwszej i drugiej instrukcji Problem: jaką wartość $4 pobierze trzecia instrukcja? zakończenie wykonania drugiej instrukcji przed zakończeniem pierwszej spowoduje, że trzecia instrukcja pobierze wartość rejestru$4 zapisaną przez pierwszą instrukcję Niejednoznaczność ta jest nazywana hazardem W-A-W (zapis po zapisie) procesor musi zagwarantować poprawne wykonanie takiej sekwencji instrukcji
Hazardy W-A-R oraz W-A-W Hazardy te nie wynikają z prostej zależności instrukcji zależność między instrukcjami w przypadku WAR daje się zauważyć po odwróceniu kolejności instrukcji zależności tego rodzaju nazywa się zależnościami wstecznymi, zależnościami fałszywymi lub antyzależnościami Usunięcie hazardów W-A-R i W-A-W wymaga zrozumienia przyczyny ich powstania
Mechanizm powstawania hazardów R-A-W oraz W-A-W { // sekwencje odwołań // powodujące hazardy // oznaczono kolorami { // wersja bez hazardów int a1, a2, a3, a4, a5, x; int a,x; a1 = 1; x = a1 + 20; a = 1; x = a + 20; a2 = 2; x = a2 + 3; a = 2; // W-A-R x = a + 3; a3 = 3; x = a3 / 2; } a = 3; // W-A-R x = a / 2; a = 4; // W-A-W i W-A-R a = 5; x = a - 3; } a4 = 4; a5 = 5; x = a5-3;
Źródła hazardów W-A-R oraz W-A-W Powodem powstawania hazardów jest wielokrotne używanie tych samych zmiennych (rejestrów procesora) do przechowywania różnych wartości Wynika to z: ograniczonej liczby rejestrów dostępnych w procesorze dążenie do przejrzystego zapisu programu (użycie małej liczby zmiennych / rejestrów) pętlowej struktury programów w kolejnych obiegach pętli zmienia się wartość zmiennych Rozwiązanie: zwiększenie liczby dostępnych rejestrów najlepiej do nieskończoności
Usuwanie hazardów W-A-R i W-A-W Ograniczona liczba rejestrów wynika: ze skończonej powierzchni krzemu w układzie procesora zajętości pamięci przez kody instrukcji w każdej instrukcji trzeba zapisać numery rejestrów Rozwiązanie: wyposażenie procesora w większą liczbę rejestrów niż wynika to z modelu programowego dynamiczne przypisywanie rejestrów fizycznych do numerów rejestrów modelu programowego technika ta jest nazywana przemianowywaniem rejestrów (register renaming)
Przemianowywanie rejestrów realizacja Każda instrukcja opuszczająca stopień szeregujący otrzymuje nowy fizyczny rejestr docelowy, zastępujący numer rejestru modelu programowego W kolejnych instrukcjach specyfikujących ten rejestr jako źródłowy numer rejestru źródłowego modelu programowego zostaje zastąpiony przez numer rejestru fizycznego przypisanego danemu rejestrowi modelu programowego Rejestr fizyczny jest zwalniany przy zakończeniu wykonania następnej instrukcji o tym samym numerze rejestru docelowego w modelu programowym Procesor musi uwzględniać (przywracać) kolejność programową instrukcji przy ich kończeniu
Przemianowywanie rejestrów przykład Instrukcja w programie Przypisanie numerów rejestrów EAX EBX ECX (start) 0 1 2 mov eax,3 4 1 2 r4 3 mov ebx,10 4 5 2 r5 10 Instrukcja wewnątrz procesora add ebx, eax 4 6 2 r6 r5 + r4 add ebx,ecx 4 7 2 r7 r6 + r2 mov ecx,20 4 7 8 r8 20 add ebx,ecx 4 9 8 r9 r7 + r8 add eax,ebx 10 9 8 r10 r4 + r9
DZIĘKUJĘ ZA UWAGĘ!