Zakładając, że żądania pamięci podręcznej L1 i L2 powodują błąd, czy procesor się zatrzymuje do momentu uzyskania dostępu do pamięci głównej?
Słyszałem o pomyśle przejścia na inny wątek, jeśli tak, to co jest używane do obudzenia zablokowanej nici?
Zakładając, że żądania pamięci podręcznej L1 i L2 powodują błąd, czy procesor się zatrzymuje do momentu uzyskania dostępu do pamięci głównej?
Słyszałem o pomyśle przejścia na inny wątek, jeśli tak, to co jest używane do obudzenia zablokowanej nici?
Odpowiedzi:
Opóźnienie pamięci jest jednym z podstawowych problemów badanych w badaniach architektury komputerowej.
Wykonanie spekulacyjne z problemem instrukcji poza kolejnością jest często w stanie znaleźć użyteczną pracę do wypełnienia opóźnienia podczas trafienia w pamięć podręczną L1, ale zwykle kończy się przydatna praca po około 10 lub 20 cyklach. Podjęto kilka prób zwiększenia ilości pracy, którą można wykonać w przypadku opóźnienia spowodowanego długim opóźnieniem. Jednym z pomysłów była próba wykonania prognozy wartości (Lipasti, Wilkerson i Shen, (ASPLOS-VII): 138-147, 1996). Ten pomysł był przez pewien czas bardzo modny w kręgach badawczych architektury akademickiej, ale wydaje się, że nie sprawdza się w praktyce. Ostatnią próbą uratowania prognozy wartości ze śmietnika historii była egzekucja runahead(Mutlu, Stark, Wilkerson i Patt (HPCA-9): 129, 2003). W wykonaniu runahead rozpoznajesz, że twoje przewidywania wartości będą błędne, ale i tak wykonujesz spekulacyjnie, a następnie wyrzucasz całą pracę na podstawie prognozy, zgodnie z teorią, że przynajmniej zaczniesz jakieś prefiksy dla czegoś, co w przeciwnym razie byłoby pamięcią podręczną L2 tęskni. Okazuje się, że Runahead marnuje tyle energii, że po prostu nie jest tego warte.
Ostateczne podejście w tym stylu, które może zyskać trochę trakcji w przemyśle, polega na stworzeniu wyjątkowo długich buforów zmiany kolejności. Instrukcje są wykonywane spekulacyjnie na podstawie przewidywania gałęzi, ale nie są przewidywane wartości. Zamiast tego wszystkie instrukcje zależne od obciążenia o dużym opóźnieniu nie są wyświetlane i czekają w buforze zmiany kolejności. Ale ponieważ bufor zmiany kolejności jest tak duży, że możesz nadal pobierać instrukcje, jeśli predyktor gałęzi wykonuje przyzwoitą pracę, czasem będziesz w stanie znaleźć przydatną pracę znacznie później w strumieniu instrukcji. Wpływowym artykułem badawczym w tej dziedzinie były rurociągi o ciągłym przepływie(Srinivasan, Rajwar, Akkary, Gandhi i Upton (ASPLOS-XI): 107-119, 2004). (Pomimo faktu, że wszyscy autorzy pochodzą z Intela, uważam, że pomysł zyskał większą przyczepność w AMD.)
Korzystanie z wielu wątków w celu uzyskania tolerancji na opóźnienia ma znacznie dłuższą historię, z większym sukcesem w branży. Wszystkie udane wersje używają sprzętowej obsługi wielowątkowości. Najprostszą (i odnoszącą największe sukcesy) wersją jest często tak zwana FGMT ( wielowątkowa wielowarstwowa ) lub wielowątkowa z przeplotem . Każdy rdzeń sprzętowy obsługuje wiele kontekstów wątków ( kontekst to zasadniczo stan rejestru, w tym rejestry takie jak wskaźnik instrukcji i wszelkie rejestry niejawnych flag). W procesorze drobnoziarnistej wielowątkowe każda nić jest przetwarzany w-zamówienie. Procesor śledzi, które wątki utknęły w martwym obciążeniu o długim opóźnieniu i które są gotowe do następnej instrukcji, i korzysta z prostej strategii planowania FIFO w każdym cyklu, aby wybrać gotowy wątek do wykonania tego cyklu. Wczesnym przykładem tego na dużą skalę były procesory HEP Burton Smitha (Burton Smith zaprojektował superkomputer Tera, który był również drobnoziarnistym procesorem wielowątkowym). Ale myślę, że ten pomysł sięga daleko wstecz, aż do lat 60. XX wieku.
FGMT jest szczególnie skuteczny w przypadku obciążeń przesyłanych strumieniowo. Wszystkie nowoczesne procesory graficzne (procesory graficzne) są wielordzeniowe, przy czym każdy rdzeń to FGMT, a koncepcja ta jest również szeroko stosowana w innych domenach obliczeniowych. T1 firmy Sun był również wielordzeniowy FMGT, podobnie jak Intel Xeon Phi (procesor, który często jest nadal nazywany „MIC” i kiedyś był nazywany „Larabee”).
Idea jednoczesnego wielowątkowości (Tullsen, Eggers i Levy, (ISCA-22): 392-403, 1995) łączy wielowątkowość sprzętową z wykonywaniem spekulacyjnym. Procesor ma wiele kontekstów wątków, ale każdy wątek jest wykonywany spekulacyjnie i poza kolejnością. Bardziej zaawansowany program planujący może następnie użyć różnych heurystyk do pobrania z wątku, który najprawdopodobniej będzie miał użyteczną pracę ( Malik, Agarwal, Dhar i Frank, (HPCA-14: 50-61), 2008 ). Pewna duża firma zajmująca się półprzewodnikami zaczęła używać terminu hyperthreading do jednoczesnego wielowątkowości, a nazwa ta wydaje się być najczęściej stosowana w dzisiejszych czasach.
Po ponownym przeczytaniu twoich komentarzy uświadomiłem sobie, że jesteś zainteresowany sygnalizacją między procesorem a pamięcią. Nowoczesne pamięci podręczne zwykle pozwalają na jednoczesne wyróżnienie wielu chybień. Nazywa się to pamięcią podręczną bez blokady (Kroft, (ISCA-8): 81-87, 1981). (Ale gazeta jest trudna do znalezienia w Internecie i nieco trudna do odczytania. Krótka odpowiedź: jest wiele księgowości, ale po prostu sobie z tym radzisz. Struktura sprzętowa księgowania nazywa się MSHR (rejestr informacji o braku statusu / statusu ), jak to nazwał ją Kroft w swoim artykule z 1981 r.)
Krótka odpowiedź brzmi: nic, procesor się zatrzymuje.
Nie ma tak wielu możliwości. Przejście do innego zadania nie jest tak naprawdę opcją z dwóch powodów. Jest to kosztowna operacja, a ponieważ bieżące zadanie i inne zadanie rywalizują o miejsce w pamięci podręcznej, przełączenie na inne zadanie może samo wymagać dostępu do pamięci głównej, a więc może wrócić do pierwotnego zadania. Co więcej, musiałoby to obejmować system operacyjny, więc procesor musiałby wyzwolić jakąś formę przerwania lub pułapki - w rzeczywistości procesor przełączałby się na jakiś kod jądra.
Podczas gdy procesor jest zablokowany, zegar nadal działa, więc może wystąpić przerwanie timera lub przerwanie z innych urządzeń peryferyjnych. Tak więc zmiana kontekstu jest bardziej prawdopodobna podczas dostępu do pamięci głównej niż podczas dostępu do pamięci podręcznej, ale tylko dlatego, że zajmuje więcej czasu.
Niemniej jednak współczesne komputery zawierają różnorodne techniki mające na celu skrócenie czasu traconego przez procesor na oczekiwanie na pamięć główną. Przeciąganie zdarza się, ale tylko wtedy, gdy nie można tego uniknąć.
Jedną z technik jest pobieranie spekulatywne : procesor próbuje zgadnąć, do której lokalizacji pamięci będzie uzyskiwany dostęp, i pobiera ją w celu buforowania przed czasem. Na przykład, pętle nad blokiem pamięci są wspólne, więc jeśli załadowano linie pamięci podręcznej dla adresów pamięci 0x12340000, 0x12340010 i 0x12340020, dobrym pomysłem może być załadowanie linii dla 0x12340030. Kompilator może pomóc, generując instrukcje pobierania wstępnego, które są jak obciążenia, z wyjątkiem tego, że przesyłają one tylko dane z pamięci głównej do pamięci podręcznej, a nie do rejestru procesora.
Kolejną techniką jest wykonanie spekulacyjne . Procesor rozpoczyna wykonywanie następnej instrukcji przed wykonaniem ładowania. Dzieje się tak naturalnie ze względu na potokowanie instrukcji. W ten sposób można wykonać tylko instrukcje, które nie zależą od załadowanej wartości: procesor musi wykonać analizę zależności. W przypadku instrukcji warunkowych (np. Obciążenie r1; rozgałęzienie, jeśli r1 ≠ 0), procesory stosują heurystykę przewidywania rozgałęzień, aby odgadnąć, jaka będzie wartość. Wykonanie spekulacyjne po obciążeniu może wymagać przewinięcia na wypadek, gdyby obciążenie wywołało przerwanie.
Niektóre architektury, takie jak Itanium, ułatwiają wykonywanie instrukcji w dogodnej kolejności, umożliwiając domyślną zmianę kolejności instrukcji: zamiast składać się z sekwencji instrukcji elementarnych, które są wykonywane semantycznie jedna po drugiej, programy składają się z bardzo długich słów instrukcji : pojedyncza instrukcja zawiera wiele operacji, które mają być wykonywane równolegle przez różne komponenty procesora.
Przełączanie na inny wątek odbywa się podczas hiperwątkowania , znajdującego się w wysokiej klasy procesorach x86. Jest to technika projektowania sprzętowego: każdy rdzeń procesora zawiera dwa oddzielne banki rejestrów (każdy odpowiadający kontekstowi zadania), ale pojedyncze wystąpienie innych elementów, dzięki czemu może obsługiwać dwa niezależne wątki wykonania, ale skutecznie wykonywać instrukcje tylko z jednego na czas. Podczas gdy jeden wątek jest zablokowany, drugi wątek jest kontynuowany. Z punktu widzenia oprogramowania istnieją dwa niezależne procesory; po prostu zdarza się, że te procesory mają wiele elementów pod maską.
Zamiana to jeszcze jeden poziom w hierarchii pamięci podręcznej: pamięć główna może być postrzegana jako pamięć podręczna dla przestrzeni wymiany. Przy wymianie mechanizmy i wskaźniki wydajności są różne. Jeśli zadanie wymaga załadowania danych z wymiany, instrukcja ładowania uruchamia pułapkę, która wykonuje kod jądra w celu przydzielenia strony w pamięci RAM i załadowania jej zawartości z dysku. Gdy tak się dzieje, jądro może zdecydować się na przejście do innego zadania.
Odpowiedź na to pytanie będzie się różnić w zależności od architektury. Podczas gdy wiele procesorów przestaje działać (ARM, xtht bez hiperwątkowania itp.), Ponieważ przełączanie wątków zajmuje im zbyt dużo czasu, nie jest to podejście stosowane przez każdą architekturę. W niektórych architekturach każdy wątek zaplanowany na CPU ma swój własny niezależny plik rejestru, więc procesor może po prostu wykonywać pracę z wątku, który nie czeka na dostęp do pamięci. Rozumiem, że jest to w ograniczonym zakresie to, co robi hyperthreading x86 (używając tylko 2 wątków), ale jest znacznie bardziej powszechny na GPGPUarchitektury. W szczególnym przypadku CUDA co najmniej kilkadziesiąt, jeśli nie setki, wypaczeń wątków jest zwykle ładowanych na dany multiprocesor w danym momencie, przy czym każdy wątek (setki lub tysiące) ma własne rejestry. Pozwala to architekturze na wykonanie instrukcji z innego wątku w następnym cyklu, gdy dany wątek wydaje dostęp do pamięci. Tak więc, dopóki załadowanych jest wystarczająca liczba wątków, rdzenie procesora nigdy nie pozostają bezczynne w celu uzyskania dostępu do pamięci. Aby uzyskać więcej informacji, zobacz Wytyczne dotyczące wydajności i hierarchia pamięci .