Kapitel 2
This commit is contained in:
parent
59e62c74a3
commit
077b380459
@ -5,9 +5,16 @@ author: Robert Jeutter
|
|||||||
---
|
---
|
||||||
|
|
||||||
# Einführung
|
# Einführung
|
||||||
> Rechnerarchitektur = Programmierschnittstelle + Interner Aufbau
|
> Rechnerarchitektur = Programmierschnittstelle + Interner Aufbau\\
|
||||||
> Einheit von Struktur und Funktion
|
> Einheit von Struktur und Funktion
|
||||||
|
|
||||||
|
- Programmierschnittstelle
|
||||||
|
- Schnittstelle zwischen Rechner und Benutzer bzw. der Hardware und der untersten Softwareschicht
|
||||||
|
- Befehlssatzarchitektur (Instruction Set Architecture)
|
||||||
|
- Interner Aufbau
|
||||||
|
- Hardware-Aufbau von Komponenten, die die Rechnerarchitektur realisieren
|
||||||
|
- Speichereinheiten, Recheneinheiten, Verbindungssysteme,
|
||||||
|
|
||||||
Abstraktionsebenen eines Rechnersystems
|
Abstraktionsebenen eines Rechnersystems
|
||||||
| Anwendungsprogramm | Java, C,... |
|
| Anwendungsprogramm | Java, C,... |
|
||||||
| Assemblerprogramm | Betriebssystem-Ebene |
|
| Assemblerprogramm | Betriebssystem-Ebene |
|
||||||
@ -21,31 +28,338 @@ Grundarchitekturen:
|
|||||||
- Harvard (Zugriff direkt durch Prozessor)
|
- Harvard (Zugriff direkt durch Prozessor)
|
||||||
- Princton/von-Neumann (Zugriff über Systembus)
|
- Princton/von-Neumann (Zugriff über Systembus)
|
||||||
|
|
||||||
- Speicher, Steuerwerk: Daten und Instruktionen speichern; beinhaltet Programmzähler um Ausführung zu steuern
|
| Speicher | Daten und Instruktionen speichern |
|
||||||
- Rechenwerk: auch ALU (Arithmetic and Logic Unit) um Berechnung durchzuführen
|
| Steuerwerk | beinhaltet Programmzähler um Ausführung zu steuern |
|
||||||
- Daten aus Hauptspeicher in Register laden
|
| Rechenwerk | auch ALU (Arithmetic and Logic Unit) um Berechnung durchzuführen
|
||||||
- Berechnungsaufgaben durchführen
|
Üblicherweise besitzt eine Recheneinheit (CPU) Daten- oder Rechenregister (Registermaschine). Berechnungen werden ausschließlich mit den Registern vorgenommen.
|
||||||
- Ergebnisse in Hauptspeicher ablegen
|
- Daten aus Hauptspeicher in Register laden
|
||||||
|
- Berechnungsaufgaben durchführen
|
||||||
|
- Ergebnisse in Hauptspeicher ablegen
|
||||||
|
|
||||||
Programmiermodelle
|
Klassifikation von Befehlssatzarchitekturen
|
||||||
- CISC - Complex Instruction Set Computers
|
- 0-Operand (Stack): Add
|
||||||
- RISC - Reduced Instruction Set Computers
|
- 1-Operand (Akkumulator): Add R1
|
||||||
- MIPS - Microprozessor without interlocked pipeline stages
|
- 2-Operand: Add R1, R3
|
||||||
|
- 3-Operand: Add R1, R2, R3
|
||||||
|
|
||||||
|
|
||||||
|
# Prozessorarchitektur
|
||||||
|
Programmiermodelle, Instruction Set Architectures (ISAs):
|
||||||
|
Klassifikation von Befehlssätzen nach der Gestaltung/Ausprägung der vorhandenen Maschinenbefehle
|
||||||
|
|
||||||
|
| CISC | RISC | MIPS |
|
||||||
|
| -- | -- | -- |
|
||||||
|
| Complex Instruction Set Computing | Reduced Instruction Set Computing | Microprocessor without interlocked pipeline stages |
|
||||||
|
| Einfache und komplexe Befehle | Nur einfache Befehle | |
|
||||||
|
| Heterogener Befehlssatz | Orthogonaler Befehlssatz | |
|
||||||
|
| Verschiedene Taktzahl pro Befehl | Meist 1 Takt pro Befehl | |
|
||||||
|
| Viele Befehlscode-Formate mit unterschiedlicher Länge | Wenige Befehlscode-Formate mit einheitlicher Länge | |
|
||||||
|
| Mikroprogrammwerk | Direktverdrahtung | |
|
||||||
|
| Vermischung von Verarbeitungs- und Speicherbefehlen | Trennung von Verarbeitungs- und Speicherbefehlen | |
|
||||||
|
| schwierig, unter CPI = 2 zu kommen | CPI möglichst nicht über 1 | |
|
||||||
|
|
||||||
> Unter dem CPI (cycles per instruction) -Wert einer Menge von Maschinenbefehlen versteht man die mittlere Anszahl der Taktzyklen pro Maschinenbefehl
|
> Unter dem CPI (cycles per instruction) -Wert einer Menge von Maschinenbefehlen versteht man die mittlere Anszahl der Taktzyklen pro Maschinenbefehl
|
||||||
|
|
||||||
|
|
||||||
Master-Slave Flip-Flops
|
## Einzelzyklusmaschine
|
||||||
- Master übernimmt Wert bei steigender Taktflanke
|
- Programmzähler (32 bit, PZ, engl. Program Counter, PC)
|
||||||
- Slave übernimmt Wert bei fallender Taktflanke
|
- Speichert und liefert die aktuelle auszuführende Instruktionsadresse
|
||||||
- Instruktionszyklus beginnt bei fallender Taktflanke
|
- an den Instruktionsspeicher (b) und das Addierwerk (a)
|
||||||
|
- übernimmt die Adresse der Folgeinstruktion (c)
|
||||||
|
- Addierwerk
|
||||||
|
- Fortlaufende Addition mit 4, da 4-Byte Instruktionen
|
||||||
|
- Der neue Wert für PZ wird im Register gespeichert (c)
|
||||||
|
- Die hintersten 2 Bit im PZ sind immer Null
|
||||||
|
- Instruktionsspeicher
|
||||||
|
- Liefert die auszuführende Maschineninstruktion
|
||||||
|
- Instruktionswort (32 bit)
|
||||||
|
- Gelesener Wert erscheint am Ausgang des Speichers
|
||||||
|
- Instruktionsformat bestimmt den weiteren Ablauf
|
||||||
|
- Master-Slave Flip-Flops
|
||||||
|
- Master übernimmt Wert bei steigender Taktflanke
|
||||||
|
- Slave übernimmt Wert bei fallender Taktflanke
|
||||||
|
- Instruktionszyklus beginnt bei fallender Taktflanke
|
||||||
|
- Ansteuerung des Registersatzes
|
||||||
|
- Register immer auslesen (kein Takt) und Transport zur ALU
|
||||||
|
- Schreiben des Zielregisters Register[rd] am Ende der Taktperiode
|
||||||
|
- Zeit für Speicherzugriff und für die primäre ALU muss eingeplant werden
|
||||||
|
- Ausgabe des Instruktionsspeichers wird über die ganze Dauer gehalten
|
||||||
|
- Vorzeichenerweiterung des Direktoperanden von 16 auf 32 Bit
|
||||||
|
- Erleichtert die Unterbringung kleiner Konstanten im Befehlswort
|
||||||
|
- Vom Steuerwerk aus abschaltbar für „unsigned“ Befehle
|
||||||
|
|
||||||
|
### Ausführungsphase
|
||||||
|
- ALU-Registeroperationen
|
||||||
|
- Operanden im Register oder als
|
||||||
|
- Direktoperand
|
||||||
|
- Üblicher Satz an ALU-Operationen
|
||||||
|
- Register $0 liefert Wert 0
|
||||||
|
- Adressierung von Variablen im Speicher
|
||||||
|
- Adressrechnung in der primären ALU
|
||||||
|
- Basisregister plus Direktoperand
|
||||||
|
- Registerinhalt lesen/schreiben
|
||||||
|
- Load/Store-Architektur
|
||||||
|
- Speicheroperationen können keine Arithmetik
|
||||||
|
- also z.B. kein inc 0xaff0($7),0x0004
|
||||||
|
- ALU schon zur Adressberechnung benötigt
|
||||||
|
- Separater Addierer zur Sprungzielberechnung
|
||||||
|
- Prüfschaltung auf Gleichheit zweier Register in der primären ALU („eql“)
|
||||||
|
- Bedingte Sprünge mit einem 16-bit Direktoperanden (beq $7,$8,loop)
|
||||||
|
- Maximal möglicher Offset von ±17 Bit nach einer 2-bit Verschiebung
|
||||||
|
- Unbedingte Sprünge mit 28-bit Adresse später
|
||||||
|
|
||||||
|
### Speicherzugriff
|
||||||
|
- Getrennte Speicher für Code & Daten
|
||||||
|
- Aktuelle Instruktion wird bis zum Ende des Gesamtzyklus gehalten
|
||||||
|
- Kein zweiter Zugriff im gleichen Taktzyklus möglich
|
||||||
|
- Quellregister speichern, falls Store
|
||||||
|
- Speichersteuerung durch besonderes Schreibsignal
|
||||||
|
- Zielregister laden
|
||||||
|
- Falls Ladebefehl aus dem Speicher
|
||||||
|
- Falls Rücksprungadresse (PC-magic)
|
||||||
|
- Falls Resultat aus ALU
|
||||||
|
- ALU-Resultat nutzen
|
||||||
|
- Für „Register Write-Back“
|
||||||
|
- Als Datenspeicheradresse
|
||||||
|
- Nicht direkt speichern, wg. Load/Store-Architektur!
|
||||||
|
|
||||||
|
### Register zurückschreiben
|
||||||
|
- Nummer des Zielregisters (Zielregisterselektor)
|
||||||
|
- Stammt aus IR[15-11] oder IR[20-16], 5-bit Bereich für Werte 0-31
|
||||||
|
- Steuersignal
|
||||||
|
- Zielregister zum Ende des Instruktionszyklus schreiben
|
||||||
|
- Schreibsignal an Registersatz, falls nötig
|
||||||
|
- Pseudorelative Sprünge (jump xLabel)
|
||||||
|
- Kein separater Addierer erforderlich, nur ein zusätzlicher MUX-Eingang
|
||||||
|
- Oberste 4 Bits unverändert, untere 28 Bits werden ersetzt (4, 26, 2)
|
||||||
|
- Jump-and-Link (jal) sichert alten Programmzähler in $31 (Subroutine)
|
||||||
|
|
||||||
|
### erforderliche Steuerleitung
|
||||||
|
- Für Speicher
|
||||||
|
- 2-bit Steuersignal: 0/8/16/32 Bit zum Datenspeicher schreiben
|
||||||
|
- Instruktionsspeicher liest immer
|
||||||
|
- Für Registersatz
|
||||||
|
- 2-bit Steuersignal: 0/8/16/32 Bit zum Registerfile schreiben
|
||||||
|
- Für 4 Multiplexer
|
||||||
|
- 2-bit Steuersignal: Auswahl des Zielregisters (1 aus 3)
|
||||||
|
- 2-bit Steuersignal: Datenquelle für Zielregister
|
||||||
|
- 2-bit Steuersignal: Sprungziel wählen
|
||||||
|
- 1-bit Steuersignal: Direkt- oder Registeroperand für ALU
|
||||||
|
- Für Arithmetik
|
||||||
|
- 1-bit Steuersignal: Vorzeichenerweiterung ja/nein
|
||||||
|
- 6-bit Steuersignal: ALU-Operation
|
||||||
|
|
||||||
|
Einzyklusmaschine ist unwirtschaftlich
|
||||||
|
- Komponenten arbeiten jeweils nur einen kleinen Teil der Gesamtzeit
|
||||||
|
- Zeitverlust bei potentiell kurzen Instruktionen
|
||||||
|
|
||||||
|
## Mehrzyklen CPU
|
||||||
|
- Gesamtzyklus der bisherigen MIPS
|
||||||
|
- Dauer des Instruktionszyklus ist die Summe der Einzelverzögerungen
|
||||||
|
- Unteraktivitäten müssen abwarten, bis die Parameter sicher vorliegen
|
||||||
|
- Anderenfalls können sich „spurious writes“ ergeben
|
||||||
|
- z.B. in Registersatz oder in den Speicher
|
||||||
|
- Mehrzyklen-CPU als Überleitung zum Fließbandprinzip
|
||||||
|
- Aufteilung der Befehlsausführung auf mehrere gleich lange Taktzyklen
|
||||||
|
- Einfügen von Registern für in den Stufen entstandene Zwischenresultate
|
||||||
|
- Noch immer nur eine Instruktion zu einem Zeitpunkt in Ausführung
|
||||||
|
- CPU-Zustand bezieht sich auf eine einzelne aktuelle Instruktion
|
||||||
|
- Pipelined CPU – mit Fließbandprinzip
|
||||||
|
- In jedem Taktzyklus beginnt eine neue Maschineninstruktion
|
||||||
|
- Mehrere Instruktionen gleichzeitig in Ausführung
|
||||||
|
- Aber unterschiedlicher Fertigstellungsgrad
|
||||||
|
- Bessere Auslastung der Hardware
|
||||||
|
- Höherer Durchsatz
|
||||||
|
- Große Pipeline-Tiefe:
|
||||||
|
- Zusätzliche Ressourcen, höherer Energieaufwand (Taktfrequenz!)
|
||||||
|
- Längere Instruktionssequenzen für gleichen oder besseren Speedup (→ Registeroverhead!)
|
||||||
|
- Bei unterschiedlichen Stufenverzögerungen bestimmt die langsamste Stufe die Taktfrequenz
|
||||||
|
- Lange Instruktionssequenzen:
|
||||||
|
- Meist wegen Daten- und Kontrollabhängigkeiten nicht machbar
|
||||||
|
- Hohe Latenz – Füllen und Leeren der Pipeline!
|
||||||
|
- Warum geht die Anzahl der Pipeline-Stufen zurück?
|
||||||
|
- hoher Energieverbrauch
|
||||||
|
- hohe Leistungseinbußen durch Kontroll- und Datenabhängigkeiten (Füllen/Leeren der Pipeline)
|
||||||
|
- mehr Parallelität in den einzelnen Pipeline-Stufen → superskalare Prozessoren
|
||||||
|
- mehr Prozessorkerne mit geringerer Leistungsaufnahme pro Kern
|
||||||
|
- Fließband-Architektur (engl. pipeline architecture): Bearbeitung mehrerer Befehle gleichzeitig, analog zu Fertigungsfließbändern.
|
||||||
|
|
||||||
|
Aufgaben der einzelnen Phasen
|
||||||
|
- Befehlsholphase
|
||||||
|
- Lesen des aktuellen Befehls; separater Speicher, zur Vermeidung von Konflikten mit Datenzugriffen
|
||||||
|
- Dekodier- und Register-Lese-Phase
|
||||||
|
- Lesen der Register möglich wegen fester Plätze für Nr. im Befehlswort
|
||||||
|
- Ausführungs- und Adressberechnungsphase
|
||||||
|
- Berechnung arithmetischer Funktion bzw. Adresse für Speicherzugriff
|
||||||
|
- Speicherzugriffsphase
|
||||||
|
- Wird nur bei Lade- und Speicherbefehlen benötigt
|
||||||
|
- Abspeicherungsphase
|
||||||
|
- Speichern in Register, bei Speicherbefehlen nicht benötigt
|
||||||
|
|
||||||
|
Pipeline-Hazards
|
||||||
|
> Structural Hazards (deutsch: strukturelle Abhängigkeiten oder Gefährdungen): Verschiedene Fließbandstufen müssen auf dieselbe Hardware-Komponente zugreifen, weil diese nur sehr aufwändig oder überhaupt nicht zu duplizieren ist.
|
||||||
|
|
||||||
|
> Definition: Ein Befehl i heißt von einem nachfolgenden Befehl j antidatenabhängig, falls j eine Speicherzelle beschreibt, die von i noch gelesen werden müsste.
|
||||||
|
|
||||||
|
> Definition: Zwei Befehle i und j heißen voneinander Ausgabeabhängig, falls i und j die selbe Speicherzelle beschreiben.
|
||||||
|
|
||||||
|
- Gleichheit der Register wird schon in der instruction decode-Stufe geprüft
|
||||||
|
- Sprungziel wird in separatem Adressaddierer ebenfalls bereits in der instruction decode-Stufe berechnet
|
||||||
|
- Sofern weiterhin noch Verzögerungen auftreten:
|
||||||
|
- nächsten Befehl einfach ausführen (delayed branch)
|
||||||
|
- oder weiterhin NOOP(s) einfügen (stall)
|
||||||
|
|
||||||
|
### Pipelining – Zusammenfassung
|
||||||
|
- Die Fließbandverarbeitung (engl. pipelining) ermöglicht es, in jedem Takt die Bearbeitung eines Befehls abzuschließen, selbst wenn die Bearbeitung eines Befehls ≥ 1 Takte dauert
|
||||||
|
- Mehrere Pipelines -> pro Takt können mehrere Befehle beendet
|
||||||
|
werden
|
||||||
|
- 3 Typen von Gefährdungen des Fließbandbetriebs:
|
||||||
|
- resource hazards
|
||||||
|
- control hazards
|
||||||
|
- data hazards (RAW, WAR, WAW)
|
||||||
|
- Gegenmaßnahmen
|
||||||
|
- pipeline stall
|
||||||
|
- branch prediction
|
||||||
|
- forwarding / bypassing
|
||||||
|
- delayed branches
|
||||||
|
- out-of-order execution
|
||||||
|
- dynamic sched
|
||||||
|
|
||||||
|
## Sprungvorhersage
|
||||||
|
Je mehr die Parallelität ausgenützt werden soll, desto mehr sind Kontrollkonflikte der limitierender Faktor!
|
||||||
|
|
||||||
|
Dynamische Sprungvorhersage
|
||||||
|
- Zur Laufzeit durch Prozessor-Hardware
|
||||||
|
- Vorhersage, ob ein bedingter Sprung genommen wird oder nicht
|
||||||
|
- Abhängig von der Vorhersage: Füllen der Prozessor-Pipeline mit Befehlen ab der vorhergesagten Programm-Stelle
|
||||||
|
- Reduktion der branch penalty, falls vorhergesagtes Programm-Verhalten mit tatsächlichem übereinstimmt
|
||||||
|
|
||||||
|
### Einfache lokale Prädiktoren
|
||||||
|
- Liefern Vorhersage, ob bedingter Sprung genommen wird oder nicht
|
||||||
|
- Prädiktion allein anhand der Historie des betrachteten, aktuellen Sprungs
|
||||||
|
- Historie eines Sprungs wird mit 1, 2 oder n Bits gepuffert
|
||||||
|
|
||||||
|
- Sprungvorhersage-Puffer
|
||||||
|
- Branch prediction buffer oder branch history table
|
||||||
|
- Kleiner Speicher, der mit (Teil der) Adresse des Sprungbefehls indiziert wird
|
||||||
|
- Verwendet nur wenige untere Bits der Adresse
|
||||||
|
- Enthält 1 Bit: Sprung beim letzten Mal ausgeführt (taken) oder nicht (not taken)
|
||||||
|
- Prädiktion: Sprung verhält sich wie beim letzten Mal
|
||||||
|
- Nachfolgebefehle ab vorhergesagter Adresse holen
|
||||||
|
- Falls Prädiktion fehlerhaft: Prädiktionsbit invertieren
|
||||||
|
- Einfachste Art von Puffer (keine Tags, d.h. keine Überprüfung, ob Adresse tatsächlich im Puffer)
|
||||||
|
- Entspricht sehr einfachem Cache
|
||||||
|
- Hat eine bestimmte Kapazität
|
||||||
|
- Kann nicht für alle Sprünge (aktuelle) Einträge enthalten
|
||||||
|
- Reduziert branch penalty nur, wenn branch delay länger als Berechnung der Zieladresse mit branch prediction buffer dauert
|
||||||
|
- Prädiktion kann fehlerhaft sein
|
||||||
|
- Prädiktion kann von anderem Sprungbefehl stammen (mit gleichen Bits im Indexteil der Adressen)
|
||||||
|
|
||||||
|
- Nachteile des einfachen 1-Bit Vorhersageschemas
|
||||||
|
- Höhere Fehlerrate als überhaupt möglich, wenn Häufigkeit der Sprungentscheidungen betrachtet wird
|
||||||
|
- D.h. auch wenn Sprung fast immer ausgeführt (taken) wird, entstehen 2 Fehler anstatt 1
|
||||||
|
|
||||||
|
2-Bit Branch-Prediction Buffer
|
||||||
|
- Speicherung der Historie, Befehlsadressen als Zugriffsschlüssel:
|
||||||
|
|
||||||
|
Allgemein: n-Bit Prädiktor (Spezialfall: 2-Bit)
|
||||||
|
- Verwendet n-Bit Zähler
|
||||||
|
- Sättigungsarithmetik (kein wrap around bei Überlauf)
|
||||||
|
- Kann Werte zwischen 0 und 2 n - 1 annehmen
|
||||||
|
- Wenn Zähler größer als Hälfte des Maximums (2 n - 1): Vorhersagen, dass Sprung ausgeführt wird; ansonsten vorhersagen, dass Sprung nicht genommen wird
|
||||||
|
- Zähler wird bei ausgeführtem Sprung inkrementiert und bei nicht ausgeführtem dekrementiert
|
||||||
|
- In der Praxis: 2-Bit Prädiktor ähnlich gut wie n-Bit Prädiktor
|
||||||
|
- In den meisten Prozessoren heute: 2-Bit Prädiktor für (lokale) Vorhersage
|
||||||
|
- Einschränkung des n-Bit (bzw. 2-Bit) Prädiktors:
|
||||||
|
- Betrachtet nur (vergangenes) Verhalten eines Sprungs, um dessen (zukünftiges) Verhalten vorherzusagen.
|
||||||
|
- Arbeitet rein lokal!
|
||||||
|
- Idee: Verbesserung durch Betrachtung des Verhaltens anderer Sprünge
|
||||||
|
- Man erhält so genannten korrelierenden Prädiktor (correlating predictor) oder zweistufigen Prädiktor
|
||||||
|
- Prinzip: Aufgrund globaler Information (anderer Sprünge) wird einer von mehreren lokalen Prädiktoren ausgewählt
|
||||||
|
|
||||||
|
|
||||||
P39 16-Bit Operandten version i statt r
|
### Korrelierende Prädikatoren
|
||||||
|
- Beziehen zur Vorhersage des Verhaltens eines Sprungs Kontext-Information mit ein, d.h. die Historie anderer Sprungbefehle
|
||||||
|
- Prädiktor benutzt globale Kontext-Bits, um einen von mehreren lokalen Prädiktoren auszuwählen
|
||||||
|
|
||||||
|
- Betrachten wiederholte Ausführung des Codefragments (ignorieren dabei alle anderen Sprünge, inkl. dem für Wiederholung)
|
||||||
|
- Einschränkung: Statt aller möglicher Sequenzen: d wechselt zwischen 2 und 0
|
||||||
|
|
||||||
# Prozessorarchitektur
|
Zweistufiger Prädiktor
|
||||||
|
- Verwendet 1 Bit Kontextinformation
|
||||||
|
- Es existieren 2 lokale Prädiktoren, beide je 1-Bit
|
||||||
|
- Kontext: Letzter (i.a. anderer) Sprung wurde ausgeführt/nicht ausgeführt (1 Bit)
|
||||||
|
- Vorhersage des zweistufigen Prädiktors: Anhand des Kontexts wird lokaler Prädiktor für die Vorhersage des aktuell betrachteten Sprungs ausgewählt
|
||||||
|
- Letzter Sprung ist i.a. nicht gleich aktuellem, vorherzusagendem Sprung (nur in einfachen Schleifen)
|
||||||
|
- Notation des Prädiktorstatus: <X>/<Y> mit
|
||||||
|
- <X>: Vorhersage, falls letzter Sprung not taken, d.h. Kontext = NT
|
||||||
|
- <Y>: Vorhersage, falls letzter Sprung taken, d.h. Kontext = T
|
||||||
|
- <X> und <Y> Vorhersagen: jeweils entweder T oder NT
|
||||||
|
|
||||||
|
(m,n)-Prädiktor
|
||||||
|
- Betrachtet als Kontext das Verhalten der letzten m Sprünge, um aus $2^m$ vielen lokalen Prädiktoren einen n-Bit Prädiktor auszuwählen
|
||||||
|
- Vorteil gegenüber (rein lokalem) 2-Bit Prädiktor
|
||||||
|
- Höhere Vorhersagegenauigkeit
|
||||||
|
- Erfordert kaum Hardwareaufwand
|
||||||
|
- Sprunggeschichte (Kontext, „Ausgang“ vorangegangener Sprünge) kann in m-Bit Schieberegister gespeichert werden (1 Bit für jeden der m vielen letzten Sprünge im Kontext, Bit gleich 1 wenn Sprung taken)
|
||||||
|
- Vorhersagepuffer adressiert via Konkatenation von
|
||||||
|
- Unteren Adressbits der Sprungbefehlsadresse
|
||||||
|
- m Bit globaler Sprunggeschichte
|
||||||
|
|
||||||
|
### High Performance Befehlsdekodierung
|
||||||
|
In Hochleistungs-Pipelines ist reine Vorhersage eines Sprungs i.d.R. nicht ausreichend
|
||||||
|
- Insbesondere: Falls mehrere Befehle pro Takt auszugeben sind
|
||||||
|
- Befehlsstrom mit großer Bandbreite erforderlich!
|
||||||
|
- Kontrollflussabhängigkeiten dürfen nicht „wahrnehmbar“ sein
|
||||||
|
- Maßnahmen hierfür
|
||||||
|
- Pufferung von Sprungzielen, und nicht nur Vorhersage des Sprungverhaltens (branch target buffer)
|
||||||
|
- Integrierte Einheit für das Holen der Befehle (d.h. nicht nur [relativ] einfache erste Stufe der Pipeline)
|
||||||
|
- Vorhersage von Rücksprungadressen (bei Prozeduraufruf)
|
||||||
|
|
||||||
|
### Branch Target Buffer
|
||||||
|
5-stufige Pipeline, Auswertung von Sprungbedingungen in EX:
|
||||||
|
- Branch delay von 2 Takten
|
||||||
|
- Mit Sprungvorhersage (branch prediction buffer)
|
||||||
|
- Zugriff erfolgt in ID (Adresse des Sprungbefehls schon in IF bekannt; aber:
|
||||||
|
- evtl. angesprungenes Ziel erst nach Befehlsdecodierung [ID])
|
||||||
|
- Nächste vorhergesagte Instruktion kann erst nach ID geholt werden
|
||||||
|
- Branch delay = 1, falls Prädiktion korrekt
|
||||||
|
- Mit Pufferung des Sprungziels (branch target buffer)
|
||||||
|
- Zugriff auf branch target buffer erfolgt in IF. Verhalten wie „echter“ Cache,
|
||||||
|
- adressiert mit Sprungbefehlsadresse (überprüft, ob Cache-Hit)
|
||||||
|
- Liefert vorhergesagte Adresse als Ergebnis, d.h. nächsten PC (d.h. nicht nur Vorhersage über Sprungverhalten)
|
||||||
|
- Keine Verzögerung, falls Prädiktion korrekt!
|
||||||
|
|
||||||
|
Zusätzliche Speicherung auch des Sprungziels, z.B. Kombination mit branch prediction buffer
|
||||||
|
|
||||||
|
Bei geschickter Organisation kann das Fließband immer gefüllt bleiben; die Sprünge kosten dann effektiv keine Zeit; CPI <1 möglich.
|
||||||
|
|
||||||
|
Eigenschaften
|
||||||
|
- Verzögerung durch Sprung kann vollständig vermieden werden (sofern Vorhersage korrekt), da bereits in IF Entscheidung über nächsten Befehlszähler (PC) getroffen wird.
|
||||||
|
- Da Entscheidung allein auf Basis des PC getroffen wird, muss überprüft werden, ob Adresse im Puffer (impliziert, dass Sprungbefehl vorliegt)
|
||||||
|
- Speicherung im Prinzip nur für Sprünge notwendig, die als ausgeführt vorhergesagt werden (not taken = normale sequentielle Dekodierung geht weiter)
|
||||||
|
- Achtung – bei falscher Vorhersage
|
||||||
|
- Entsteht ursprüngliche Sprung-Verzögerung, plus
|
||||||
|
- Aufwand zur Aktualisierung des Vorhersagepuffers
|
||||||
|
|
||||||
|
### Integrierte Befehls-Hol-Einheit (IF Unit)
|
||||||
|
Insbesondere mit Blick auf multiple-issue Prozessoren eigene (autonome) funktionale Einheit für Befehlsholphase
|
||||||
|
- Führt Befehlscodes in Pipeline ein
|
||||||
|
- Integrierte Funktionalitäten
|
||||||
|
- Sprungvorhersage: Wird Teil der Befehlsholphase
|
||||||
|
- Instruction Pre-fetch: Insbes. um mehrere Befehle pro Takt liefern (und später ausgeben) zu können, läuft Befehlsholen weiterer Dekodierung voraus (= pre-fetch)
|
||||||
|
- Zugriff auf Befehlsspeicher: Bei mehreren Befehlen pro Takt mehrere Zugriffe erforderlich (bei Cache auf ggfs. mehrere cache lines). Werden hier koordiniert/geplant
|
||||||
|
- Befehlspuffer: Befehle können hier (lokal im Prozessor!) von Issue-Stufe nach Bedarf abgerufen werden
|
||||||
|
|
||||||
|
### Vorhersage von Rücksprungadressen
|
||||||
|
Allgemeines Ziel: Vorhersage indirekter Sprünge (d.h. bzgl. Basisadresse in Register)
|
||||||
|
- Hauptverwendung: Rückkehr aus Prozeduraufrufen
|
||||||
|
- MIPS: Prozeduraufruf per jal proc, Rückkehr per jr $31
|
||||||
|
- Vorhersage mit branch target buffer schlecht, da Aufruf aus unterschiedlichen Codeteilen heraus möglich
|
||||||
|
- Methode: (Stack-) Speicher für Rücksprungadressen
|
||||||
|
- Push bei Prozeduraufruf (call), und
|
||||||
|
- Pop bei Rücksprung (return)
|
||||||
|
- Vorhersagequalität „perfekt“, wenn Stack-Puffer größer als maximale Aufruftiefe
|
||||||
|
|
||||||
|
|
||||||
# Speicherarchitektur
|
# Speicherarchitektur
|
||||||
|
Loading…
Reference in New Issue
Block a user