Kapitel 2
This commit is contained in:
		
							parent
							
								
									59e62c74a3
								
							
						
					
					
						commit
						077b380459
					
				| @ -5,9 +5,16 @@ author: Robert Jeutter | ||||
| --- | ||||
| 
 | ||||
| # Einführung | ||||
| > Rechnerarchitektur = Programmierschnittstelle + Interner Aufbau | ||||
| > Rechnerarchitektur = Programmierschnittstelle + Interner Aufbau\\ | ||||
| > 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 | ||||
| | Anwendungsprogramm | Java, C,... | | ||||
| | Assemblerprogramm | Betriebssystem-Ebene | | ||||
| @ -21,31 +28,338 @@ Grundarchitekturen: | ||||
| - Harvard (Zugriff direkt durch Prozessor) | ||||
| - Princton/von-Neumann (Zugriff über Systembus) | ||||
| 
 | ||||
| - Speicher, Steuerwerk: Daten und Instruktionen speichern; beinhaltet Programmzähler um Ausführung zu steuern | ||||
| - Rechenwerk: auch ALU (Arithmetic and Logic Unit) um Berechnung durchzuführen | ||||
|     - Daten aus Hauptspeicher in Register laden | ||||
|     - Berechnungsaufgaben durchführen | ||||
|     - Ergebnisse in Hauptspeicher ablegen | ||||
| | Speicher | Daten und Instruktionen speichern | | ||||
| | Steuerwerk | beinhaltet Programmzähler um Ausführung zu steuern | | ||||
| | Rechenwerk | auch ALU (Arithmetic and Logic Unit) um Berechnung durchzuführen | ||||
| Üblicherweise besitzt eine Recheneinheit (CPU) Daten- oder Rechenregister (Registermaschine). Berechnungen werden ausschließlich mit den Registern vorgenommen. | ||||
| - Daten aus Hauptspeicher in Register laden | ||||
| - Berechnungsaufgaben durchführen | ||||
| - Ergebnisse in Hauptspeicher ablegen | ||||
| 
 | ||||
| Programmiermodelle | ||||
| - CISC - Complex Instruction Set Computers | ||||
| - RISC - Reduced Instruction Set Computers | ||||
| - MIPS - Microprozessor without interlocked pipeline stages | ||||
| Klassifikation von Befehlssatzarchitekturen | ||||
| - 0-Operand (Stack): Add | ||||
| - 1-Operand (Akkumulator): Add R1 | ||||
| - 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 | ||||
| 
 | ||||
| 
 | ||||
| Master-Slave Flip-Flops | ||||
| - Master übernimmt Wert bei steigender Taktflanke | ||||
| - Slave übernimmt Wert bei fallender Taktflanke | ||||
| - Instruktionszyklus beginnt bei fallender Taktflanke | ||||
| ## Einzelzyklusmaschine | ||||
| - Programmzähler (32 bit, PZ, engl. Program Counter, PC) | ||||
|   - Speichert und liefert die aktuelle auszuführende Instruktionsadresse | ||||
|   - 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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user