Według projektu cyfrowego i architektury komputerowej autorstwa Harrisa i Harrisa istnieje kilka sposobów implementacji procesora MIPS, w tym:
Mikroarchitektury pojedynczy cykl wykonuje całą instrukcji w jednym cyklu. (...)
W Multicycle mikroarchitektury instrukcje wykonywany w serii krótszych cyklach. (...)
Potokowych mikroarchitektury stosuje odbierania wiadomości do mikroarchitektury pojedynczym cyklu.
Architektury są często klasyfikowane jako RISC lub CISC. Z RISC vs. CISC :
Procesory RISC używają tylko prostych instrukcji, które można wykonać w ciągu jednego cyklu zegara.
Ponieważ MIPS jest architekturą RISC, jestem trochę zdezorientowany powyższymi definicjami i zastanawiam się, czy nie ma między nimi jakiejś sprzeczności. Dokładniej:
- Jeśli instrukcję RISC można podzielić na krótsze cykle (Fetch, Decode, ...), to jak możemy powiedzieć, że wykonanie całej instrukcji zajmuje tylko jeden cykl zegara? Czy wykonanie każdego z kroków nie wymaga jednego cyklu zegara ?
- Czy tak naprawdę wykonanie jednego polecenia RISC zajmuje jeden cykl zegara? Co się dzieje, na przykład, jeśli wystąpi brak pamięci podręcznej i procesor musi czekać na wolną pamięć DRAM? Czy nie powinno to znacznie wydłużyć czasu wykonania instrukcji?
- Czym dokładnie jest jeden cykl instrukcji? Czy to czas potrzebny na zakończenie jednej instrukcji (tj. Jeden / kilka cykli zegara)?
- Jak długo trwa jedna instrukcja CISC w cyklach zegara / instrukcji?
Odpowiedzi:
Praktyczne definicje RISC i CISC są tak zamazane i niewyraźne, że prawie nie mają znaczenia. Teraz najlepiej jest myśleć o nich bardziej jako o „filozofii”, w tym sensie, że architektura CISC ma bogatszy zestaw instrukcji z mocniejszymi instrukcjami indywidualnymi (np. DIV i tym podobne), podczas gdy zestaw instrukcji RISC jest czysty i szybki, i pozostawia kompilatorowi wdrożenie złożonych operacji. Nawet rzekomo zestawy instrukcji CISC (jak x86) są tłumaczone na instrukcje wewnętrzne zarówno w procesorach Intel, jak i AMD i zaimplementowane bardziej jak procesory RISC. Aby odpowiedzieć na twoje pytania:
Oryginalne akademickie procesory RISC (i myślę, że być może pierwsze komercyjne wersje) rzeczywiście wykonywały jedną instrukcję na cykl, w tym pobieranie i dekodowanie. Było to możliwe, ponieważ ścieżki danych były super czyste, ponieważ operacje na każdym etapie były proste i dobrze zdefiniowane. (kompromis tutaj to tylko bardzo proste instrukcje, które można wdrożyć w ten sposób). Gdy uderzy w prawdziwy świat, wszystko się zatarło. Rzeczy takie jak potokowanie i architektura superskalarna uniemożliwiają prostą dychotomię RISC / CISC.
Oryginalne układy RISC próbowały wykonać jedną instrukcję na cykl i mogły, gdyby dane były dostępne w pliku rejestru. Oczywiście, gdyby procesor musiał przejść do pamięci DRAM, zajęłoby to (dużo) dłużej. RISC polega na „próbie” wykonania instrukcji na cykl.
Jeden cykl instrukcji to czas między pobraniem.
In zależy w ogromnym stopniu od instrukcji i architektury zestawu instrukcji. Nawet w architekturze CISC niektóre instrukcje mogą być wykonywane bardzo szybko (na przykład przesunięcie w lewo lub w prawo). Niektóre wykonywane bardzo wolno (10s lub więcej cykli). Architektura VAX (prawdopodobnie szczyt filozofii CISC) zawierała bardzo złożone instrukcje. Nawiasem mówiąc, architektura CISC jest zwykle łatwiejsza do programowania w asemblerze niż architektura RISC, ponieważ jest prawie jak język wysokiego poziomu!
źródło
Krótka odpowiedź
Kroki dekodowania i wykonywania instrukcji są wykonywane równolegle z następnym krokiem poprzedniej instrukcji. Ta technika jest znana jako potokowanie. Zobacz procesory RISC poniżej.
Architektura RISC z pojedynczym wydaniem zwykle uśrednia nieco mniej niż jedną instrukcję na cykl ze względu na stany oczekiwania i czas potrzebny na operacje ładowania / przechowywania, które uderzają w pamięć, a nie tylko rejestrację w celu rejestracji. Automaty opóźniające dają ci architektoniczny haczyk, który może ci pomóc odzyskać trochę tego czasu. Zobacz procesory RISC poniżej.
Cykl instrukcji to czas potrzebny do wykonania instrukcji. Zależy to od architektury i (w niektórych przypadkach) instrukcji. Na przykład większość instrukcji dotyczących czegoś takiego jak MIPS R2000 / 3000 zajmuje jeden cykl. Instrukcje dotyczące dostępu do pamięci (ładuj / zapisz, gałąź) zajmują więcej niż jeden cykl, chociaż szczeliny opóźniające oznaczają, że możesz być w stanie wykonać coś innego (być może po prostu NOP) w szczelinie opóźniającej. Architektura niepotokowa może mieć cykle instrukcji składające się z kilku cykli zegara, często zmieniających się w zależności od trybu adresowania. Zobacz procesory RISC, tradycyjne architektury CISC i architektury przewodowe poniżej.
Projekty z wieloma wydaniami mogą nieco zatrzeć tę koncepcję, wykonując jednocześnie więcej niż jedną instrukcję.
Procesory CISC mogą mieć instrukcje o różnym czasie trwania. Dokładna liczba cykli zegara zależy od architektury i instrukcji. Różna liczba cykli zegarowych podejmowanych przez ISA CISC jest jednym z powodów, dla których trudno jest je wbudować w mocno potokowe architektury. Zobacz Tradycyjne architektury CISC poniżej.
Dłuższa odpowiedź
W przypadku pojedynczego wydania MIPS, SPARC lub innego procesora wszystkie instrukcje (dla pierwszego przybliżenia) wydają się w jednym cyklu, chociaż mogą mieć coś, co nazywane jest „slotem opóźnienia”.
Na procesorach RISC
W tym kontekście procesor z pojedynczym problemem to taki, w którym procesor nie wykonuje żadnej analizy zależności w locie i równoległego wydawania instrukcji tak, jak robią to współczesne procesory, tj. Mają tylko jedną jednostkę wykonawczą, która wykonuje instrukcje w kolejność, w jakiej są czytane z memoty. Więcej na ten temat później.
Większość starszych procesorów RISC to projekty z jednym wydaniem, a te typy są nadal szeroko stosowane w systemach wbudowanych. 32-bitowy pojedynczy rdzeń całkowity RISC może być zaimplementowany w około 25 000-30 000 bramek, więc rdzenie tego typu mają bardzo niskie zużycie energii i bardzo małe wymiary. Dzięki temu można je łatwo i tanio zintegrować z produktami SOC (system-on-chip).
Projekty procesorów RISC są przetwarzane potokowo - przetwarzanie instrukcji odbywa się w kilku etapach, przy czym każda instrukcja jest przekazywana potokiem do następnego etapu w każdym cyklu zegara. W większości przypadków pojedynczy potokowy procesor wykona coś blisko jednej instrukcji na cykl zegara.
Niektóre architektury mają instrukcje takie jak rozgałęzianie lub ładowanie / przechowywanie z pamięci, w której dodatkowy cykl podjęty przez dostęp do pamięci jest widoczny dla kodu.
Na przykład w projekcie SPARC V7 / V8 następna instrukcja po wykonaniu odgałęzienia, zanim nastąpi rozgałęzienie. Zazwyczaj umieszczasz NOP w gnieździe po gałęzi, ale możesz włożyć do niego inną instrukcję, jeśli możesz znaleźć coś pożytecznego do zrobienia.
Architektura MIPS R2000 / R3000 miała podobne gniazdo opóźnienia w instrukcjach ładowania / przechowywania. Jeśli załadowałeś wartość z pamięci, nie pojawiłaby się ona w rejestrze dla innego cyklu. Możesz umieścić NOP w gnieździe lub zrobić coś innego, jeśli znajdziesz coś pożytecznego do zrobienia, co nie zależy od właśnie uruchomionej operacji ładowania.
Jeśli pamięć była wolniejsza niż procesor, co często się zdarzało, możesz uzyskać dodatkowe stany oczekiwania na dostęp do pamięci. Stany oczekiwania zamrażają procesor przez co najmniej jeden cykl zegara, aż dostęp do pamięci zostanie zakończony. W praktyce te stany oczekiwania i dodatkowy czas na dostęp do pamięci oznaczają, że projekty CPU z pojedynczym wydaniem mają średnio nieco mniej niż jedną instrukcję na cykl zegara. Sloty opóźnień dają pewne możliwości optymalizacji kodu poprzez wykonanie innej instrukcji podczas operacji pamięci.
Tradycyjne procesory CISC
Procesory CISC były projektami, które mogły mieć instrukcje o różnym czasie trwania. Często mieli bardziej złożone instrukcje zaimplementowane bezpośrednio w sprzęcie, które musiałyby być wykonane w oprogramowaniu procesora RISC.
Większość architektur komputerów mainframe i prawie wszystkie projekty komputerów PC aż do M68K i intel 386 były tradycyjnymi mikrokodowanymi procesorami CISC. Te projekty okazały się wolniejsze na zegar i wykorzystywały więcej bramek niż procesory RISC.
Mikrokod
Przykład architektury mikrokodowanej (MOS 6502) można zobaczyć tutaj w emulacji . Mikrokod można zobaczyć na górze obrazu.
Mikrokod kontroluje przepływy danych i akcje aktywowane w CPU w celu wykonania instrukcji. Przechodząc przez kolejne kroki mikrokodu, możesz aktywować części procesora, przenosząc dane przez ALU lub wykonując inne kroki. Komponenty wielokrotnego użytku w CPU mogą być koordynowane przez wiele cykli zegara w celu wykonania instrukcji. W przypadku 6502 niektóre działania potokowe mogą być również wykonane przez mikrokod.
Mikrokodowane konstrukcje wykorzystywały mniej krzemu niż wbudowane układy scalone kosztem potencjalnie zajmowania kilku cykli zegara w celu wykonania instrukcji. W zależności od projektu procesory te wymagałyby różnej długości czasu na instrukcję.
Architektura przewodowa
Projekty przewodowe (niekoniecznie wykluczające się wzajemnie z mikrokodem) wykonują instrukcje synchronicznie lub mogą mieć własnych koordynatorów, którzy wykonują coś w wielu cyklach zegara. Zazwyczaj są one szybsze kosztem bardziej dedykowanego sprzętu, a zatem są droższe we wdrożeniu niż mikrokodowana konstrukcja o równoważnej funkcjonalności.
Znanym tego przykładem był oryginalny procesor Amdahl 470/6 , który zastępował procesor w niektórych modelach IBM System / 370. Procesor Amdahl był projektem przewodowym w czasie, gdy 370 procesorów IBM było w dużej mierze oparte na mikrokodzie. Procesor Amdahl był około 3 razy szybszy niż procesory IBM, które zastąpiły.
Nie trzeba dodawać, że IBM nie był rozbawiony, co doprowadziło do bitwy sądowej, która ostatecznie zmusiła IBM do otwarcia architektury mainframe do czasu wygaśnięcia dekretu zgody kilka lat temu.
Zazwyczaj projekt przewodowy tego typu wciąż nie był tak szybki taktowanie zegara, jak procesor RISC, ponieważ różne czasy i formaty instrukcji nie pozwalały na tak duży zakres potokowania, jak projekt RISC.
Projekty wielokrotnego wydania
Większość współczesnych procesorów to architektury o wielu problemach, które mogą przetwarzać więcej niż jedną instrukcję na raz w jednym wątku. Układ może wykonać dynamiczną analizę zależności od strumienia przychodzących instrukcji i wydawać instrukcje równolegle, gdy nie ma zależności od wyniku poprzedniego obliczenia.
Przepustowość tych układów zależy od tego, ile równoległości można osiągnąć w kodzie, ale większość współczesnych procesorów uśrednia kilka instrukcji na cykl na większości kodów.
Współczesne procesory Intel i inne procesory ISA x86 / X64 mają warstwę, która interpretuje oldschoolowy zestaw instrukcji CISC w mikro instrukcje, które mogą być przekazywane przez potokowy rdzeń w stylu RISC z wieloma problemami. Dodaje to narzut, który nie występuje w procesorach z ISA, które są zaprojektowane do potokowania (tj. Architektury RISC, takie jak ARM lub PowerPC).
Projekty VLIW
Projekty VLIW, z których Intel Itanium jest chyba najbardziej znany, nigdy nie wystartowały jako architektury głównego nurtu, ale w IIRC istnieje wiele architektur DSP, które używają tego typu projektów. Projekt VLIW wyraźnie uwidacznia wiele wydań za pomocą słowa instrukcji zawierającego więcej niż jedną instrukcję wydawaną równolegle.
Były one zależne od dobrych kompilatorów optymalizujących, które identyfikowały zależności i możliwości równoległości, upuszczając instrukcje do wielu gniazd dostępnych dla każdego słowa instrukcji.
Architektury VLIW działają całkiem dobrze w aplikacjach numerycznych, ponieważ operacje macierzowe / macierzowe oferują zwykle możliwości szerokiej równoległości. Itanium przez jakiś czas miał niszę na rynku aplikacji superkomputerowych, a przynajmniej jedna architektura superkomputerów - Multiflow TRACE - została wyprodukowana przy użyciu tego typu ISA.
Pamięć i buforowanie
Współczesne procesory są znacznie, dużo szybsze niż pamięć, więc bezpośrednie odczyty z pamięci mogą generować setki stanów oczekiwania, które blokują procesor do momentu uzyskania dostępu do pamięci. Buforowanie, teraz wykonywane w wielu warstwach, przechowuje ostatnio używane lokalizacje pamięci w pamięci podręcznej. Ponieważ procesory zwykle spędzają większość czasu na wykonywaniu kodu w pętlach, oznacza to, że uzyskuje się dobry wskaźnik ponownego wykorzystywania ostatnio używanych lokalizacji pamięci. Ta właściwość nazywa się „lokalizacją odniesienia”.
Gdy uzyskasz lokalizację odniesienia, procesor może działać z prędkością zbliżoną do optymalnej. Brakuje pamięci podręcznej do następnego poziomu i powoduje szereg stanów oczekiwania; Chybienie w pamięci podręcznej do pamięci głównej może spowodować setki.
Zatem faktyczna przepustowość układów CPU może być silnie zależna od wydajności wzorców dostępu do pamięci. Całe książki zostały napisane na temat optymalizacji kodu w tym celu i jest to złożony temat sam w sobie.
źródło
To uproszczenie dla studentów.
Każdy nietrywialny procesor jest przetwarzany potokowo. Na jednym końcu znajdują się instrukcje dotyczące przeszukiwania jednostki pobierania wstępnego, kilka jednostek wykonawczych w środku wykonujących rzeczywistą pracę, oraz jednostka problemowa odpowiedzialna za zadeklarowanie instrukcji ukończonych po zakończeniu zapisu do rejestru lub pamięci. Jeśli istnieje wiele jednostek wykonawczych (powiedzmy liczba całkowita ALU, zmiennoprzecinkowa jednostka ALU i jednostka wektorowa), może być możliwe wydanie (czasami nazywane „wycofaniem”) wielu instrukcji na cykl zegara. W jaki sposób procesor może dostarczyć więcej niż jedną instrukcję na cykl? idzie o wiele więcej szczegółów na ten temat.
Jak mówisz, co się stanie, jeśli wystąpi opóźnienie braku pamięci podręcznej? Intel Hyperthreading jest nowatorskim rozwiązaniem tego problemu: dwie partie rejestrów stanu procesora, jedna partia logiki sterowania i jednostek emisji. Gdy tylko jeden wirtualny procesor się zatrzyma, przełącz się na stan drugiego. (jest to samo uproszczenie rażące)
Wynika to z tego, że współczesne podręczniki procesora dają dużo mniej precyzyjne instrukcje, a dużo trudniej jest napisać precyzyjny cykl taktowania, jeśli na przykład próbujesz wyprowadzać wideo w czasie rzeczywistym ze sprzętu, który nie powinien być w stanie tego zrobić .
(Konkretną odpowiedzią na „Jak długo trwa jedna instrukcja CISC w cyklach zegara / instrukcji?” Jest „zajrzyj do instrukcji producenta i będzie ona miała czas na instrukcję”)
źródło
Inni faceci napisali wiele dobrych materiałów, więc krótko streszczę: w dawnych czasach (tutaj w 1980 roku) rozważano 8-bitowe procesory dnia (6800, 6502, Z80, 6809 i inne) CISC. Niektóre instrukcje mogły być wykonywane w 2 cyklach zegarowych, ale były to proste instancje, takie jak ustawianie / kasowanie flag bitów w rejestrze statusu procesora. Wykonanie innych instrukcji może zająć od 2 do 6, a nawet do 9 cykli zegara. Te procesory miały dość mocne instrukcje, Z80 miał pewne instrukcje czyszczenia bloku pamięci, które zapisywałyby tę samą wartość w szeregu bajtów w pamięci, skutecznie usuwając duży blok w jednej instrukcji, wystarczy skonfigurować kilka rejestrów i wykonać Instrukcja LDIR (ładowanie, zwiększanie i powtarzanie).
Procesor 6502 (z pamięci) miał 56 instrukcji, ale 13 trybów adresowania, tworząc potężny zestaw instrukcji.
RISC przyszedł długo i przyjął inne podejście, ma garść instrukcji, które wszystkie wykonują w jednym cyklu zegara. Programy są zwykle dłuższe i zajmują więcej pamięci, ponieważ instrukcje są proste w tym, jakie operacje wykonują, więc potrzebujesz ich więcej.
Jeśli dobrze pamiętam, pierwszą próbą architektury RISC był procesor transputerowy lub Acorn Risc?
źródło