Potokowość
Pipelingi instruktażowe to technika stosowana przy projektowaniu nowoczesnych mikroprocesorów, mikrokontrolerów i procesorów w celu zwiększenia wydajności ich instrukcji (liczby instrukcji, które mogą być wykonane w jednostce czasu).
Główną ideą jest podział (określany jako "split") przetwarzania instrukcji procesora, zdefiniowanego przez mikrokod instrukcji, na szereg niezależnych kroków mikrooperacji (zwanych również "mikroinstrukcjami", "mikroop" lub "µop"), z pamięcią na końcu każdego kroku. Pozwala to układowi sterującemu procesorów na obsługę instrukcji z szybkością przetwarzania najwolniejszego kroku, która jest znacznie szybsza niż czas potrzebny do przetworzenia instrukcji jako pojedynczego kroku.
Termin "rurociąg" odnosi się do faktu, że każdy z etapów posiada jedną mikrostrukturę (jak kropla wody), a każdy etap jest połączony z innym etapem (analogicznie; podobnie jak w przypadku rurociągów wodnych).
Większość nowoczesnych procesorów jest napędzana przez zegar. Procesor składa się wewnętrznie z logiki i pamięci (klapki). Gdy nadejdzie sygnał z zegara, klapki zapisują swoje nowe wartości, po czym logika potrzebuje czasu na zdekodowanie nowych wartości. Następnie nadchodzi kolejny impuls zegarowy, a klapki zapisują kolejne wartości i tak dalej. Poprzez rozbicie układu logicznego na mniejsze części i wstawienie klapki pomiędzy poszczególne części układu logicznego skraca się czas potrzebny na zdekodowanie wartości do momentu wygenerowania prawidłowych wyjść w zależności od tych wartości. W ten sposób można skrócić okres czasu. Na
przykład rurociąg RISC jest podzielony na pięć etapów za pomocą zestawu klapek pomiędzy poszczególnymi etapami w następujący sposób:
- Aport instruktażowy
- Dekodowanie instrukcji i pobieranie rejestrów
- Wykonać
- Dostęp do pamięci
- Zarejestruj się odpisać
Procesory z orurowaniem składają się wewnętrznie z etapów (modułów), które mogą pół-niezależnie pracować na oddzielnych mikrostrukturach. Każdy etap jest połączony klapkami z kolejnym etapem (jak "łańcuch") tak, że wyjście etapu jest wejściem do kolejnego etapu, aż do momentu wykonania zadania przetwarzania instrukcji. Taka organizacja wewnętrznych modułów procesora skraca całkowity czas przetwarzania instrukcji.
Architektura nie-rurowa nie jest tak wydajna, ponieważ niektóre moduły CPU są bezczynne, podczas gdy inny moduł jest aktywny podczas cyklu instrukcji. Pipelining nie eliminuje całkowicie jałowego czasu pracy procesora w układzie potokowym, ale spowodowanie, że moduły CPU pracują równolegle, zwiększa przepustowość instrukcji.
Mówi się, że rurociąg z instrukcjami jest w pełni orurowany, jeśli może przyjąć nową instrukcję w każdym cyklu zegara. Rurociąg, który nie jest w pełni poprowadzony, ma cykle oczekiwania, które opóźniają jego przebieg.
Podstawowy pięciostopniowy rurociąg w maszynie RISC (IF = Instruction Fetch, ID = Instruction Decode, EX = Execute, MEM = Memory access, WB = Register write back). Oś pionowa to kolejne instrukcje, oś pozioma to czas. Tak więc w zielonej kolumnie, najwcześniejsza instrukcja jest w fazie WB, a ostatnia instrukcja jest w trakcie pobierania instrukcji.
Zalety i wady systemu rurociągowego
Zalety Pipeliningu:
- Czas cyklu procesora jest zredukowany, co zwiększa przepustowość instrukcji. Pipelining nie skraca czasu potrzebnego do wykonania instrukcji, lecz zwiększa liczbę instrukcji, które mogą być przetwarzane jednocześnie ("na raz") i zmniejsza opóźnienie pomiędzy wykonanymi instrukcjami (zwane "przepustowością").
Im więcej etapów potoku ma procesor, tym więcej instrukcji może on przetworzyć "na raz" i tym mniejsze jest opóźnienie między ukończonymi instrukcjami. Każdy produkowany obecnie główny
mikroprocesor ogólnego przeznaczenia wykorzystuje co najmniej 2 etapy potoku do 30 lub 40 etapów. - W przypadku zastosowania pipelingu, jednostka CPU Arithmetic logic może być zaprojektowana szybciej, ale będzie bardziej złożona.
- Pipelining w teorii zwiększa wydajność w stosunku do nie zmontowanego rdzenia o współczynnik liczby etapów (zakładając, że częstotliwość zegara również wzrasta o ten sam współczynnik), a kod jest idealny do wykonania rurociągu.
- Procesory połączone szeregowo zasadniczo pracują z częstotliwością wyższą niż częstotliwość zegara RAM (od 2008 r. technologie RAM pracują z niskimi częstotliwościami w porównaniu z częstotliwościami procesorów), co zwiększa ogólną wydajność komputerów.
Wady Pipelinga:
Pipelining ma wiele wad, chociaż istnieje wiele technik używanych przez projektantów procesorów i kompilatorów do pokonania większości z nich; poniżej znajduje się lista typowych wad:
- Konstrukcja procesora niewyposażonego w układ scalony jest prostsza i tańsza w wykonaniu, procesor niewyposażony w układ scalony wykonuje jednocześnie tylko jedną instrukcję. Zapobiega to opóźnieniom w oddziałach (w systemie Pipelining każdy oddział jest opóźniony), jak również problemom związanym z równoczesnym wykonywaniem instrukcji seryjnych.
- W procesorze potokowym wstawianie klapek między modułami zwiększa opóźnienie instrukcji w porównaniu z procesorem niepotokowym.
- Procesor niepipelowany będzie miał zdefiniowaną przepustowość instrukcji. Wydajność procesora potokowego jest znacznie trudniejsza do przewidzenia i może się znacznie różnić dla różnych programów.
- Wiele projektów obejmuje rurociągi o długości 7, 10, 20, 31, a nawet więcej etapów; wadą długiego rurociągu jest to, że gdy program rozgałęzia się, cały rurociąg musi zostać przepłukany (oczyszczony). Większa przepustowość potoków jest mniejsza, gdy wykonywany kod zawiera wiele rozgałęzień: procesor nie może z góry wiedzieć, gdzie odczytać następną instrukcję i musi poczekać na zakończenie instrukcji rozgałęzienia, pozostawiając za sobą potok pusty. Tę wadę można zmniejszyć, przewidując, czy warunkowa instrukcja rozgałęziająca będzie rozgałęziać się na podstawie poprzedniej aktywności. Po rozwiązaniu odgałęzienia, następna instrukcja musi przejść całą drogę przez potok, zanim jej wynik będzie dostępny i procesor wznowi "pracę" ponownie. W takich ekstremalnych przypadkach wydajność procesora potokowego może być gorsza niż procesora niepotokowego.
- Niestety, nie wszystkie instrukcje są niezależne. W prostym rurociągu, wykonanie instrukcji może wymagać 5 etapów. Aby działać z pełną wydajnością, rurociąg ten będzie musiał wykonać 4 kolejne niezależne instrukcje, podczas gdy pierwsza jest wykonywana. Każda z tych 4 instrukcji może zależeć od wyjścia pierwszej instrukcji, powodując, że logika sterująca potokiem będzie czekać i włożyć do potoku przeciągnięcie lub zmarnowany cykl zegara do momentu rozwiązania zależności. Na szczęście, techniki takie jak spedycja mogą znacznie zmniejszyć liczbę przypadków, w których wymagane jest przeciągnięcie.
- Samo-modyfikujące się programy mogą nie wykonać się poprawnie na architekturze potokowej, gdy zmodyfikowane instrukcje znajdują się w pobliżu wykonywanych instrukcji. Może to być spowodowane tym, że instrukcje mogą już znajdować się w kolejce Prefetch Input, więc modyfikacja może nie wejść w życie dla nadchodzącego wykonania instrukcji. Skrytki instruktażowe jeszcze bardziej pogłębiają ten problem.
- Zagrożenia: Kiedy programista (lub kompilator) pisze kod zespołu, zazwyczaj zakłada, że każda instrukcja jest wykonywana przed wykonaniem kolejnej. Gdy założenie to nie jest potwierdzone przez potok, powoduje to, że program zachowuje się niepoprawnie, sytuacja ta jest znana jako zagrożenie. Istnieją
różne techniki rozwiązywania zagrożeń lub pracy wokół nich, takie jak przekierowywanie i opóźnianie (poprzez wstawianie przeciągnięcia lub zmarnowanego cyklu zegara).
Przykłady
Rurociąg ogólny
Po prawej stronie znajduje się ogólny rurociąg z czterema etapami:
- Fetch
- Dekodować
- Wykonać
- Pismo zwrotne
Górne szare pole to lista instrukcji oczekujących na wykonanie; dolne szare pole to lista instrukcji, które zostały wykonane, a środkowe białe pole to rurociąg.
Wykonanie jest następujące:
Czas | Wykonanie |
0 | Na wykonanie czekają cztery instrukcje |
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | Wszystkie instrukcje są wykonywane |
Bańka
W przypadku wystąpienia "czkawki" (przerwania) w wykonaniu, w rurociągu tworzy się "bańka", w której nie dzieje się nic użytecznego. W cyklu 2 pobieranie fioletowej instrukcji jest opóźnione, a etap dekodowania w cyklu 3 zawiera teraz bańkę. Wszystko, co znajduje się za fioletową instrukcją, jest również opóźnione, ale wszystko, co znajduje się przed fioletową instrukcją, jest kontynuowane w trakcie jej wykonywania.
Oczywiście, w porównaniu z powyższą egzekucją, bańka daje całkowity czas wykonania 8 ticków zegara zamiast 7.
Pęcherzyki są jak stragany (opóźnienia), w których nie dzieje się nic użytecznego do pobierania, dekodowania, wykonywania i zapisywania. To jest jak kod NOP (skrót od No OPeration).
Przykład 1
Typową instrukcją dodawania dwóch liczb może być ADD A, B, C
, który dodaje wartości znalezione w lokalizacjach pamięci A i B, a następnie umieszcza wynik w lokalizacji pamięci C. W procesorze potokowym kontroler potoku rozbiłby to na szereg zadań podobnych do tych, które wykonuje:
Lokalizacje "R1" i "R2" są rejestrami w CPU. Wartości przechowywane w lokalizacjach pamięci oznaczonych "A" i "B" są ładowane (kopiowane) do tych rejestrów, a następnie dodawane, a wynik jest przechowywany w lokalizacji pamięci oznaczonej "C".
W tym przykładzie rurociąg jest trzystopniowym, długim ładunkiem, wykonaniem i składowaniem. Każdy z tych etapów nazywany jest etapem rurociągu.
W przypadku procesora niewyposażonego w sterownik, tylko jeden etap może pracować jednocześnie, więc cała instrukcja musi zostać ukończona przed rozpoczęciem następnej. W przypadku procesora wyposażonego w układ potokowy, wszystkie etapy mogą pracować jednocześnie nad różnymi instrukcjami. Tak więc kiedy ta instrukcja jest na etapie wykonywania, druga instrukcja będzie na etapie dekodowania, a trzecia instrukcja będzie na etapie pobierania.
Przykład 2
Aby lepiej zrozumieć tę koncepcję, możemy przyjrzeć się teoretycznemu 3-stopniowemu rurociągowi:
Scena | Opis |
Ładunek | Przeczytaj instrukcję z pamięci |
Wykonać | Wykonać instrukcję |
Sklep | Zapisywanie wyników w pamięci i/lub rejestrach |
i pseudokodową listę zespołów do wykonania:
W ten sposób zostałby wykonany:
Zegar 1 | ||
Ładunek | Wykonać | Sklep |
LOAD |
|
|
Instrukcja LOAD jest pobierana z pamięci.
Zegar 2 | ||
Ładunek | Wykonać | Sklep |
MOVE | LOAD |
|
Instrukcja LOAD jest wykonywana, natomiast instrukcja MOVE jest pobierana z pamięci.
Zegar 3 | ||
Ładunek | Wykonać | Sklep |
DODAĆ | MOVE | LOAD |
Instrukcja LOAD znajduje się w fazie Store, gdzie jej wynik (liczba 40) zostanie zapisany w rejestrze A. W międzyczasie realizowana jest instrukcja MOVE. Ponieważ musi ona przenieść zawartość A do B, musi czekać na zakończenie instrukcji LOAD.
Zegar 4 | ||
Ładunek | Wykonać | Sklep |
SKLEP | DODAĆ | MOVE |
Załadowana zostaje instrukcja STORE, natomiast zakończona zostaje instrukcja MOVE i następuje obliczenie ADD.
I tak dalej. Zauważ, że czasami instrukcja będzie zależała od wyniku innego (jak na przykład nasz przykład MOVE). Kiedy więcej niż jedna instrukcja odwołuje się do konkretnego miejsca dla operandu, albo odczytuje go (jako wejście) albo zapisuje (jako wyjście), wykonanie tych instrukcji w innej kolejności niż oryginalna kolejność programu może prowadzić do sytuacji zagrożenia (wymienionej powyżej).
Ogólny 4-stopniowy rurociąg; kolorowe pola przedstawiają niezależne od siebie instrukcje
Bańka w cyklu 3 opóźnia wykonanie
Powiązane strony
- Rurociąg (obliczanie)
- Obliczenia równoległe
- Równoległość na poziomie instrukcji
Pytania i odpowiedzi
P: Co to jest pipelining instrukcji?
O: Łączenie instrukcji (ang. Instruction Pipelining) to technika stosowana w konstrukcji nowoczesnych mikroprocesorów, mikrokontrolerów i procesorów w celu zwiększenia przepustowości instrukcji poprzez podzielenie przetwarzania instrukcji procesora na szereg niezależnych kroków z przechowywaniem danych na końcu każdego kroku.
P: Jak działa pipelining?
O: Pipelining polega na podzieleniu układu logicznego na mniejsze części i wstawieniu klapek pomiędzy części układu logicznego, co skraca czas potrzebny układowi logicznemu na zdekodowanie wartości do wygenerowania prawidłowych wyjść w zależności od tych wartości. Dzięki temu można uzyskać szybsze okresy zegarowe.
P: Jakie są przykłady rurociągów?
O: Przykładem rurociągu jest rurociąg RISC, który jest podzielony na pięć etapów z zestawem klapek pomiędzy każdym etapem.
P: Jak pipelining zwiększa przepustowość instrukcji?
O: Potokowanie zwiększa przepustowość instrukcji, umożliwiając modułom procesora pracę równoległą, co skraca czas bezczynności podczas cyklu instrukcji i zwiększa całkowity czas przetwarzania.
P: Czy każdy potok jest w pełni pipelinowany?
O: Nie, nie każdy potok jest w pełni potokowy; niektóre potoki mają cykle oczekiwania, które opóźniają postęp w potoku.