Procesory

Predykcja rozgałęzień programu

przeczytasz w 3 min.

Jednym ze sposobów na ominięcie problemów związanych ze zbyt częstym opróżnianiem potoku wykonawczego i związanymi z tym stratami wydajności jest wykorzystanie mechanizmu predykcji rozgałęzień programu. Zadaniem jednostki przewidywania rozgałęzień programu jest wydedukowanie, czy aktualnie wczytywane instrukcje będą rzeczywiście wykonywane, czy też należy zacząć pobierać zupełnie inną część programu.

Działanie jednostki przewidywania skoków i rozgałęzień programu polega na analizie historii dotychczas wykonywanego kodu – chodzi o to, że jeżeli pętla lub skok warunkowy zostały raz powtórzone, to prawdopodobieństwo ich ponownego wykonania jest znacznie większe niż przejście do dalszej części programu – oraz śledzeniu programu „w  przód”. Za tę ostatnią czynność odpowiada bufor transakcji wyprzedzających TLB (ang. Transaction Lookahead Buffer). Jednostka TLB do swoich rejestrów pobiera i analizuje kolejne instrukcje przeznaczone do ewentualnego wykonania.

Umieszczenie jednostki TLB w mikroarchitekturze procesorów Intel Core i3, i5 i i7 z rdzeniem Nehalem, Core 2 oraz AMD Opteron 2000 (czterordzeniowy, serwerowy układ o kodowej nazwie Barcelona)
Umieszczenie jednostki TLB w mikroarchitekturze procesorów Intel Core i3, i5 i i7 z rdzeniem Nehalem, Core 2 oraz AMD Opteron 2000 (czterordzeniowy, serwerowy układ o kodowej nazwie Barcelona) 

Co ważne, moduł predykcji rozgałęzień analizuje nie tylko informacje związane z potokiem wykonawczym, ale również zawartość pamięci podręcznej L1 i L2 procesora – za sprowadzanie danych z pamięci RAM do pamięci podręcznej L3 oraz, w zależności od modelu procesora, z L3 do L2 odpowiedzialny jest zwykle oddzielny moduł wykonawczy.

Działanie tego mechanizmu, nazywanego też mechanizmem wstępnego pobierania danych, który często określa się mianem Execution Trace Cache lub Data Pre-fetch, polega na wyprzedzającej analizie ciągów instrukcji pod kątem wykorzystywanych przez kod programu obszarów (adresów) pamięci. Układ przewidywania decyduje o tym, które fragmenty kodu mają zostać usunięte z  pamięci cache odpowiedniego poziomu, a jakie dane mają w  niej pozostać. Sprawne działanie mechanizmu wstępnego pobierania danych jest niezwykle istotne z punktu widzenia wydajności całego procesora, gdyż chybienie w  przewidywaniach związanych z danymi, które mają znaleźć się w pamięci cache wymaga dziesięciokrotnie dłuższego czasu niż opróżnienie i  ponowne napełnienie potoku. W takiej sytuacji straty wydajności w  działaniu procesora, w zależności na którym poziomie pamięci cache nastąpiło chybienie, mogą wynosić grubo ponad sto cykli zegarowych.

Wykonywanie rozkazów poza kolejnością

Kolejnym, niezmiernie istotnym mechanizmem usprawniającym potokową pracę procesorów jest system wykonywania rozkazów poza kolejnością (ang. Out of Order Execution). Dzięki temu procesor nie musi kolejno wykonywać rozkazów, tak jak są one fizycznie umieszczone w programie, ale zmienić kolejność ich wykonywania w taki sposób, aby optymalnie wykorzystać swoje jednostki wykonawcze.

Aby można było wykonywać instrukcje poza kolejnością wykorzystywany jest specjalny mechanizm buforowania. Instrukcje po wyjściu z dekodera trafiają do specjalnego bufora ROB (ang. ReOrder Buffer), w którym mieści się kilkadziesiąt kolejnych instrukcji programu. Moduł Out of Order Execution analizuje ten zbiór rozkazów i określa najlepszą - z  punktu widzenia maksymalnego wykorzystania jednostek wykonawczych procesora - kolejność ich wykonania. Instrukcje do dalszego ich wykonania pobierane są z bufora ROB już nie w kolejności takiej jak w  programie, ale w kolejności ustalonej przez moduł Out of Order Execution, w  której wyeliminowano jak najwięcej zależności zachodzących jednocześnie między nimi i tak, aby mogły być wykonywane w  jak największym stopniu niezależnie. Dodatkowo, ze względu na ograniczoną liczbę rejestrów, muszą też zostać zaimplementowane mechanizmy przemianowywania rejestrów. Po wykonaniu rozkazów  instrukcjom przywracana jest ich właściwa kolejność.

Umieszczenie jednostki TLB w mikroarchitekturze procesorów Intel Core i3, i5 i i7 z rdzeniem Nehalem, Core 2 oraz AMD Opteron 2000 (czterordzeniowy, serwerowy układ o kodowej nazwie Barcelona)
Umieszczenie bufora ROB w mikroarchitekturze procesorów z rdzeniem o  kodowej nazwie Nehalem (Intek Core i3, i5, i7 poprzedniej generacji)

Umożliwienie zmiany kolejności wykonywania instrukcji pozwoliło na wyeliminowanie większość sytuacji, w których potok wykonawczy oczekuje na spełnienie wszystkich warunków koniecznych do wykonania danego rozkazu (np. na dane) i nie wykonuje żadnych operacji. Zamiana kolejności wykonywania instrukcji pozwala bowiem w czasie, w którym wykonywanie danej instrukcji jest wstrzymane, na płynne przejście do wykonywania innych instrukcji. W wypadku gdy procesor, tak jak współczesne układy, może jednocześnie realizować zadania w kilku potokach, proces ten jest jeszcze bardziej zoptymalizowany. Strumień instrukcji, przegrupowywany przez moduł Out of Order Execution jest wówczas tak, aby rozkazy wykonywane były jak najszybciej we wszystkich potokach wykonawczych, a potoki były maksymalnie wykorzystywane.