Laut Digital Design und Computer Architecture von Harris und Harris gibt es verschiedene Möglichkeiten, einen MIPS-Prozessor zu implementieren:
Die Einzelzyklus-Mikroarchitektur führt einen gesamten Befehl in einem Zyklus aus. (...)
Die Mikroarchitektur mit mehreren Rädern führt Anweisungen in einer Reihe von kürzeren Zyklen aus. (...)
Die Pipeline-Mikroarchitektur wendet das Pipeline- Verfahren auf die Einzelzyklus-Mikroarchitektur an.
Architekturen werden häufig als RISC oder CISC klassifiziert. Aus RISC vs. CISC :
RISC-Prozessoren verwenden nur einfache Anweisungen, die innerhalb eines Taktzyklus ausgeführt werden können.
Da es sich bei MIPS um eine RISC-Architektur handelt, bin ich ein wenig durch die obigen Definitionen verwirrt und frage mich, ob zwischen ihnen kein Widerspruch besteht. Genauer:
- Wenn ein RISC-Befehl in kürzere Zyklen aufgeteilt werden kann (Abrufen, Dekodieren, ...), wie können wir dann sagen, dass nur ein Taktzyklus erforderlich ist, um den gesamten Befehl auszuführen? Benötigt man nicht einen Takt, um jeden der Schritte auszuführen ?
- Benötigt man wirklich einen Taktzyklus, um einen RISC-Befehl auszuführen? Was passiert zum Beispiel, wenn ein Cache-Miss auftritt und der Prozessor auf langsamen DRAM warten muss? Sollte dies nicht die Ausführung des Befehls um einiges verlängern?
- Was genau ist ein Befehlszyklus? Ist es die Zeit, die es dauert, bis ein Befehl beendet ist (dh ein / mehrere Taktzyklen)?
- Wie lange dauert ein CISC-Befehl in Takt- / Befehlszyklen?
Antworten:
Die praktischen Definitionen von RISC und CISC sind so verschwommen und verschwommen, dass sie fast bedeutungslos sind. Nun ist es am besten, sie als "Philosophie" in dem Sinne zu betrachten, dass eine CISC-Architektur einen umfangreicheren Befehlssatz mit leistungsstärkeren Einzelbefehlen (z. B. DIV und dergleichen) aufweist, während ein RISC-Befehlssatz einfach und schnell ist. und überlässt es dem Compiler, komplexe Operationen zu implementieren. Selbst angeblich werden CISC-Befehlssätze (wie x86) in interne Anweisungen sowohl auf Intel- als auch auf AMD-Chips übersetzt und eher wie RISC-Prozessoren implementiert. Um Ihre Fragen zu beantworten:
Die ursprünglichen akademischen RISC-Prozessoren (und ich glaube, die allerersten kommerziellen Versionen) haben tatsächlich einen Befehl pro Zyklus ausgeführt, einschließlich Abrufen und Dekodieren. Dies war möglich, weil die Datenpfade sehr sauber waren, da die Vorgänge in jeder Phase einfach und klar definiert waren. (der Kompromiss hier ist nur sehr einfache Anweisungen können auf diese Weise implementiert werden). Sobald es die reale Welt traf, wurden die Dinge unscharf. Dinge wie Pipelining und superskalare Architektur machen eine einfache RISC / CISC-Dichotomie unmöglich.
Die ursprünglichen RISC-Chips versuchten, einen Befehl pro Zyklus auszuführen, und sie konnten, wenn die Daten in der Registerdatei verfügbar waren. Natürlich würde es (viel) länger dauern, wenn der Prozessor auf DRAM gehen müsste. Bei RISC wird versucht, einen Befehl pro Zyklus auszuführen.
Ein Befehlszyklus ist die Zeit, die zwischen den Abrufen vergeht.
Dies hängt enorm von der Anweisung und der Anweisungssatzarchitektur ab. Selbst in einer CISC-Architektur können einige Befehle sehr schnell ausgeführt werden (wie zum Beispiel eine Verschiebung nach links oder rechts). Einige wurden sehr langsam ausgeführt (10s oder mehr Zyklen). Die VAX-Architektur (wahrscheinlich der Höhepunkt der CISC-Philosophie) enthielt Anweisungen, die wirklich komplex waren. Im Übrigen ist eine CISC-Architektur in der Regel einfacher in Assembler zu programmieren als eine RISC-Architektur, da sie fast wie eine Hochsprache ist!
quelle
Die kurze Antwort
Die Schritte zum Decodieren und Ausführen des Befehls werden parallel zum nächsten Schritt des vorherigen Befehls ausgeführt. Diese Technik wird als Pipelining bezeichnet. Siehe Auf RISC-Prozessoren weiter unten.
Eine RISC-Architektur mit einem einzigen Problem weist aufgrund der Wartezustände und der Zeit, die für Lade- / Speicheroperationen benötigt werden, die auf den Speicher treffen, im Durchschnitt etwas weniger als einen Befehl pro Zyklus auf, als nur registriert zu werden. Delay Slots geben Ihnen einen architektonischen Haken, mit dem Sie einen Teil dieser Zeit zurückbekommen können. Siehe Auf RISC-Prozessoren weiter unten.
Ein Befehlszyklus ist die Zeitdauer, die zum Ausführen eines Befehls benötigt wird. Dies hängt von der Architektur und (in einigen Fällen) von den Anweisungen ab. Zum Beispiel dauern die meisten Anweisungen auf so etwas wie einem MIPS R2000 / 3000 einen Zyklus. Anweisungen mit Speicherzugriff (Laden / Speichern, Verzweigen) dauern mehr als einen Zyklus, obwohl die Verzögerungsschlitze bedeuten, dass Sie möglicherweise etwas anderes (möglicherweise nur eine NOP) im Verzögerungsschlitz ausführen können. Architekturen ohne Pipeline können Befehlszyklen mit mehreren Taktzyklen aufweisen, die häufig mit dem Adressierungsmodus variieren. Siehe Informationen zu RISC-Prozessoren, traditionellen CISC-Architekturen und festverdrahteten Architekturen weiter unten.
Designs mit mehreren Ausgaben können dieses Konzept etwas verwischen, indem mehr als eine Anweisung parallel ausgeführt wird.
CISC-Prozessoren können Anweisungen haben, die unterschiedlich lange dauern. Die genaue Anzahl der Taktzyklen hängt von der Architektur und den Anweisungen ab. Die unterschiedliche Anzahl von Taktzyklen, die in CISC-ISAs verwendet werden, ist einer der Gründe, warum es schwierig ist, sie in Architekturen mit hoher Pipeline-Auslastung zu integrieren. Siehe traditionelle CISC-Architekturen weiter unten.
Die längere Antwort
Bei einem einzelnen MIPS-, SPARC- oder anderen CPU-Problem werden alle Anweisungen (zur ersten Annäherung) in einem Zyklus ausgegeben, obwohl sie einen sogenannten Verzögerungsschlitz haben können.
Auf RISC-Prozessoren
In diesem Zusammenhang ist eine Single-Issue-CPU eine CPU, in der keine On-the-Fly-Abhängigkeitsanalyse und keine parallele Ausgabe von Anweisungen durchgeführt wird, wie dies bei modernen CPUs der Fall ist, dh, sie haben nur eine Ausführungseinheit, in der die Anweisungen ausgeführt werden die Reihenfolge, in der sie aus dem Memoty gelesen werden. Dazu später mehr.
Bei den meisten älteren RISC-Prozessoren handelt es sich um Single-Issue-Prozessoren, die in eingebetteten Systemen immer noch weit verbreitet sind. Ein 32-Bit-Single-Issue-Integer-RISC-Kern kann in etwa 25.000 bis 30.000 Gattern implementiert werden. Daher weisen CPU-Kerne dieses Typs einen sehr geringen Stromverbrauch und eine sehr geringe Stellfläche auf. Dadurch können sie einfach und kostengünstig in SOC-Produkte (System-on-Chip) integriert werden.
RISC-CPU-Designs werden in Pipelines ausgeführt. Die Verarbeitung des Befehls erfolgt in mehreren Schritten, wobei jeder Befehl in jedem Taktzyklus über die Pipeline zur nächsten Stufe weitergeleitet wird. In den meisten Fällen führt eine Single-Issue-Pipeline-CPU ungefähr einen Befehl pro Taktzyklus aus.
Einige Architekturen verfügen über Anweisungen wie Verzweigen oder Laden / Speichern aus dem Speicher, bei denen der zusätzliche Zyklus, den der Speicherzugriff benötigt, für den Code sichtbar ist.
Beispielsweise wird in einem SPARC V7 / V8- Entwurf der nächste Befehl nach einer Verzweigung tatsächlich ausgeführt, bevor die Verzweigung selbst stattfindet. Normalerweise fügen Sie eine NOP in den Slot nach dem Zweig ein, aber Sie können eine andere Anweisung hinzufügen, wenn Sie etwas Nützliches finden.
Die MIPS R2000 / R3000- Architektur hatte einen ähnlichen Verzögerungsschlitz in den Lade- / Speicheranweisungen. Wenn Sie einen Wert aus dem Speicher geladen haben, wird er für einen weiteren Zyklus nicht im Register angezeigt. Sie könnten eine NOP in den Steckplatz einfügen oder etwas anderes tun, wenn Sie etwas Nützliches finden, das nicht von der gerade ausgegebenen Ladeoperation abhängt.
Wenn der Speicher langsamer als die CPU war, was häufig der Fall war, erhalten Sie möglicherweise zusätzliche Wartezustände bei Speicherzugriffen. Wartezustände frieren die CPU für einen oder mehrere Taktzyklen ein, bis der Speicherzugriff abgeschlossen ist. In der Praxis bedeuten diese Wartezustände und die zusätzliche Zeit für Speicherzugriffe, dass die CPU-Entwürfe mit einer Ausgabe im Durchschnitt etwas weniger als einen Befehl pro Taktzyklus ausführen. Verzögerungsslots bieten Ihnen einige Möglichkeiten, Code zu optimieren, indem Sie während einer Speicheroperation einen anderen Befehl ausführen.
Traditionelle CISC-Prozessoren
CISC-Prozessoren waren Entwürfe, bei denen Anweisungen unterschiedlich lange dauern konnten. Oft waren komplexere Anweisungen direkt in der Hardware implementiert, die in Software auf einer RISC-CPU ausgeführt werden mussten.
Die meisten Mainframe-Architekturen und nahezu alle PC-Designs bis zum M68K und Intel 386 waren herkömmliche CISC-CPUs mit Mikrocodierung. Diese Designs waren pro Takt langsamer und verwendeten mehr Gates als RISC-CPUs.
Microcode
Ein Beispiel für eine mikro Architektur (MOS 6502) kann in Emulation zu sehen hier . Der Mikrocode ist oben im Bild zu sehen.
Der Mikrocode steuert den Datenfluss und die in der CPU aktivierten Aktionen, um Anweisungen auszuführen. Durch Durchlaufen der Schritte im Mikrocode können Sie die Teile einer CPU aktivieren, Daten durch ALUs bewegen oder andere Schritte ausführen. Wiederverwendbare Komponenten in der CPU können über mehrere Taktzyklen koordiniert werden, um einen Befehl auszuführen. Im Falle des 6502 könnten einige Pipeline-Aktionen auch vom Mikrocode ausgeführt werden.
Mikrocodierte Konstruktionen verwendeten weniger Silizium als festverdrahtete Chips, wobei möglicherweise mehrere Taktzyklen erforderlich waren, um einen Befehl zu vervollständigen. Abhängig vom Design würden diese CPUs pro Befehl unterschiedlich viel Zeit in Anspruch nehmen.
Festverdrahtete Architekturen
Festverdrahtete Designs (die sich mit dem Mikrocode nicht unbedingt gegenseitig ausschließen) führen einen Befehl synchron aus oder haben möglicherweise ihre eigenen Koordinatoren, um etwas über mehrere Taktzyklen hinweg zu tun. Sie sind in der Regel schneller auf Kosten dedizierterer Hardware und daher in der Implementierung teurer als ein mikrocodiertes Design mit äquivalenter Funktionalität.
Ein berühmtes Beispiel dafür war die ursprüngliche Amdahl 470/6-CPU , die bei bestimmten IBM System / 370-Modellen als Ersatz für die CPU diente. Die Amdahl-CPU war ein festverdrahtetes Design zu einer Zeit, als die 370-CPUs von IBM stark auf Mikrocode basierten. Die Amdahl-CPU war etwa dreimal schneller als die IBM-CPUs, die sie ersetzten.
Unnötig zu erwähnen, dass IBM nicht amüsiert war und dies zu einem Gerichtsstreit führte, der IBM zwang, ihre Mainframe-Architektur zu öffnen, bis die Einverständniserklärung vor einigen Jahren auslief.
Typischerweise war ein festverdrahteter Entwurf dieses Typs immer noch nicht so schnell wie eine RISC-CPU, da die unterschiedlichen Befehlszeiten und -formate nicht so viel Spielraum für das Pipelining boten wie ein RISC-Entwurf.
Designs mit mehreren Ausgaben
Bei den meisten modernen CPUs handelt es sich um Architekturen mit mehreren Problemen , die mehr als einen Befehl gleichzeitig in einem einzelnen Thread verarbeiten können. Der Chip kann eine dynamische Abhängigkeitsanalyse des eingehenden Befehlsstroms durchführen und Befehle parallel ausgeben, wenn keine Abhängigkeit vom Ergebnis einer vorherigen Berechnung besteht.
Der Durchsatz dieser Chips hängt davon ab, wie viel Parallelität im Code erzielt werden kann, aber die meisten modernen CPUs berechnen auf den meisten Codes mehrere Befehle pro Zyklus.
Moderne Intel- und andere x86 / X64-ISA-CPUs verfügen über eine Schicht, die den CISC-Befehlssatz der alten Schule in Mikrobefehle umwandelt , die über einen RISC-ähnlichen Kern mit mehreren Problemen weitergeleitet werden können. Dies fügt einen zusätzlichen Aufwand hinzu, der auf CPUs mit ISAs, die für das Pipelining ausgelegt sind (z. B. RISC-Architekturen wie ARM oder PowerPC), nicht vorhanden ist.
VLIW entwirft
VLIW-Designs, von denen das Intel Itanium vielleicht das bekannteste ist, haben sich nie als Mainstream-Architekturen etabliert, aber IIRC gibt es eine Reihe von DSP-Architekturen, die diese Art von Design verwenden. Ein VLIW-Entwurf macht Mehrfachausgaben mit einem Anweisungswort explizit, das mehr als eine Anweisung enthält, die parallel ausgegeben wird.
Diese waren abhängig von guten optimierenden Compilern, die Abhängigkeiten und Möglichkeiten für Parallelität identifizierten und Befehle in die mehreren für jedes Befehlswort verfügbaren Slots ablegten.
VLIW-Architekturen eignen sich gut für numerische Anwendungen, da Matrix- / Array-Operationen häufig Möglichkeiten für eine umfassende Parallelität bieten. Der Itanium hatte eine Zeit lang einen Nischenmarkt für Supercomputing-Anwendungen, und es gab mindestens eine Supercomputer-Architektur - den Multiflow TRACE -, der unter Verwendung eines ISA dieses Typs hergestellt wurde.
Speicher und Caching
Moderne CPUs sind viel, viel schneller als Speicher. Daher können direkte Lesevorgänge aus dem Speicher Hunderte von Wartezuständen erzeugen, die die CPU blockieren, bis der Speicherzugriff abgeschlossen ist. Das Caching, das jetzt in mehreren Ebenen ausgeführt wird, enthält die zuletzt verwendeten Speicherorte im Cache. Da CPUs in der Regel die meiste Zeit damit verbringen, Code in Schleifen auszuführen, erhalten Sie gute Trefferquoten bei der Wiederverwendung von Speicherorten, die Sie kürzlich verwendet haben. Diese Eigenschaft wird als Referenzort bezeichnet.
Wo Sie Referenzpunkte erhalten, kann die CPU nahezu mit optimaler Geschwindigkeit arbeiten. Cache-Fehler bis zur nächsten Ebene führen zu einer Reihe von Wartezuständen. Cache-Fehler im Hauptspeicher können Hunderte verursachen.
Somit kann der tatsächliche Durchsatz von CPU-Chips stark von der Effizienz von Speicherzugriffsmustern abhängen. Es wurden ganze Bücher darüber geschrieben, wie man Code dafür optimiert, und es ist ein komplexes Thema für sich.
quelle
Es ist eine Vereinfachung für die Schüler.
Jeder nicht-triviale Prozessor ist per Pipeline verbunden. Es gibt eine Prefetch-Einheit, die Anweisungen an einem Ende schaufelt, eine Anzahl von Ausführungseinheiten in der Mitte, die die eigentliche Arbeit ausführen , und eine Ausgabeeinheit, die dafür verantwortlich ist, Anweisungen für abgeschlossen zu erklären, nachdem das Schreiben in das Register oder in den Speicher abgeschlossen ist. Wenn es mehrere Ausführungseinheiten gibt (beispielsweise eine Ganzzahl-ALU, eine Gleitkomma-ALU und eine Vektoreinheit), kann es möglich sein, mehrere Befehle pro Taktzyklus auszugeben (manchmal als "Zurückziehen" bezeichnet). Wie kann eine CPU mehr als einen Befehl pro Zyklus liefern? Hierauf wird viel näher eingegangen.
Wie Sie sagen, was ist, wenn es eine Cache-Fehlerverzögerung gibt? Intel Hyperthreading ist eine neuartige Lösung dafür: zwei viele CPU-Statusregister, eine Menge Steuerlogik und Ausgabeeinheiten. Sobald eine virtuelle CPU blockiert ist, wechseln Sie in den Status der anderen. (Dies ist eine grobe Vereinfachung selbst)
Dies hat zur Folge, dass moderne CPU-Handbücher sehr vage Zeitangaben für Anweisungen enthalten und es sehr viel schwieriger ist, zyklusgenauen Zeitcode zu schreiben, wenn Sie beispielsweise versuchen, Videos in Echtzeit von Hardware auszugeben, die dazu nicht in der Lage sein sollten .
(Spezifische Antwort auf "Wie lange dauert eine CISC-Anweisung in Takt- / Anweisungszyklen?" Ist "Schauen Sie in das Referenzhandbuch des Herstellers und es werden Zeitangaben pro Anweisung angegeben".)
quelle
Die anderen Jungs haben viel gutes Material geschrieben, also werde ich mich kurz fassen: In früheren Zeiten (hier in den 1980er Jahren) wurden die 8-Bit-Prozessoren der Zeit (6800, 6502, Z80, 6809 und andere) in Betracht gezogen CISC. Einige Befehle konnten in zwei Taktzyklen ausgeführt werden, aber dies waren einfache Anweisungen, wie das Setzen / Löschen von Flag-Bits in einem Prozessorstatusregister. Die Ausführung anderer Befehle kann zwischen 2-6 und sogar bis zu 9 Taktzyklen dauern. Diese Prozessoren hatten einige ziemlich leistungsfähige Befehle, der Z80 hatte einige Befehle zum Löschen von Speicherblöcken, die denselben Wert in eine Reihe von Bytes im Speicher schreiben würden, wodurch effektiv ein großer Block in einem einzigen Befehl gelöscht würde. Richten Sie einfach ein paar Register ein und führen Sie den Befehl aus LDIR-Anweisung (Laden, Inkrementieren und Wiederholen).
Der 6502-Prozessor (aus dem Speicher) hatte 56 Befehle, aber 13 Adressierungsmodi, die einen leistungsstarken Befehlssatz erzeugten.
RISC kam eine lange und nahm einen anderen Ansatz, eine Handvoll Anweisungen, die alle in einem einzigen Taktzyklus ausgeführt werden. Die Programme sind in der Regel länger und belegen mehr Speicher, da die Anweisungen in Bezug auf die von ihnen ausgeführten Vorgänge einfach sind und Sie mehr von ihnen benötigen.
Wenn ich mich richtig erinnere, war der erste Versuch einer RISC-Architektur entweder der Transputer oder der Acorn Risc-Prozessor?
quelle