| 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. Die Hauptaufgabe der Recheneinheit besteht darin,
> Structural Hazards ("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.
- resource hazards
- data hazards: Datenabhängigkeiten
- **Antidatenabhängig**: falls Befehl j eine Speicherzelle beschreibt, die von i noch gelesen werden müsste.
- WAR (write after read) Abhängigkeit
- **Ausgabeabhängig**: falls Befehle i und j die selbe Speicherzelle beschreiben
- WAW (write after write) Abhängigkeit
- **Datenabhängigkeit**: Operation hängt von der vorhergehenden Operation ab
- RAW (read after write) Abhängigkeit
- control hazards: Kontrollabhängigkeiten
- 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
Gegenmaßnahmen
- pipeline stall (Anhalten des Fließbandes, NOOPS(s) einfügen)
- Tag beseitigt eines der Probleme: gültiger Eintrag, falls Tag-Bits gleich sind
- Alle Sprünge, deren Adressen im Indexteil übereinstimmen, werden derselben Zelle im branch prediction buffer zugeordnet. Überprüfung mittels tags, ob es der richtige Eintrag ist.
- Allgemein: Fehlerrate von 1-Bit Prädiktor ist für Sprünge in Schleifenkonstrukten doppelt so hoch wie die Anzahl ausgeführter Sprünge
- 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
- 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 <1mö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
- Verfahren von Tomasulo erlaubt auch bei Ausgabe- und Antidatenabhängigkeiten, die Reihenfolge zu vertauschen
- Umbenennung der Register; verschiedenen Benutzungen eines Registers werden verschiedene Speicherzellen zugeordnet
- Jeder funktionalen Einheit wird eine Reservation Station zugeordnet
- Reservation Stations enthalten die auszuführende Operation und, soweit bekannt, die Operanden bzw. eine Kennzeichnung in Form von tag bits des Operanden
- Sind alle Operanden bekannt und ist die funktionale Einheit frei, so kann die Bearbeitung beginnen
- Am Ende der Bearbeitung wird das Ergebnis von allen Einheiten übernommen, die das Ergebnis benötigen
- Verteilen der Daten erfolgt vor der Abspeicherung im Registerspeicher
- Aus den tag bits geht hervor, aus welcher Einheit der Operand kommen muss
- Registeradressen werden dynamisch auf größere Anzahl von Plätzen in den Reservation Stations abgebildet, d.h. Register effektiv umbenannt. Performance-Beschränkungen wegen weniger Register werden so umgangen
### Register Renaming
- Prinzip: Verwendung temporärer Register für (logisch) neue möglicherweise interferierende Belegung
- Beispiel
- Annahme: es existieren zwei temporäre Register S und T
- Kollidierende Belegungen von F8 durch `sub.d` bzw. F6 durch `add.d` in (eindeutige) temporäre Register „umleiten“
```cpp
div.d $F0,$F2,$F4
add.d $T,$F0,$F8 // Lesen von F8, Schreiben von T (F6)
s.d $T,0($R1) // Lesen von T (F6)
sub.d S,$F10,$F14 // Schreiben von S (F8)
mul.d $F6,$F10,S // Schreiben von F6
```
- Alle Namenskonflikte durch Umbenennung auflösbar (Voraussetzung: genügend temporäre Register)
- Weitere Verwendung von F8/F6 durch S/T ersetzen!
- Wichtige Hardwarestruktur: Reservation Stations
- Zugeordnet zu funktionalen Einheiten (i.d.R. eine pro Einheit)
- Arbeitsweise von Reservation Stations
- Puffern Operanden für Befehle (sobald verfügbar/geladen)
- Müssen nicht aus Registern gelesen werden!
- Ausstehende Operanden verweisen auf Reservation Station, die Eingabe bereitstellen wird
- Bei aufeinander folgenden Schreibzugriffen auf Register: Nur letzter für Aktualisierung des Inhalts verwendet
- Wichtige Eigenschaften der Verwendung von Reservation Stations anstelle des zentralen Registersatzes
- Konfliktdetektion und Ausführungskontrolle verteilt
- Informationen in Reservation Stations bei den funktionalen Einheiten bestimmen, wann Ausführung eines Befehls möglich ist
- Ergebnisse werden direkt zu den funktionalen Einheiten (in jeweiliger Reservation Station) weitergereicht
- Erweiterte Form des Forwarding
- Realisiert implizit Register Renaming
- Möglich durch gemeinsamen Ergebnisbus (common data bus)
## Multiple-Issue mit dynamischem Scheduling
- Wesentlicher Nachteil von statischem Scheduling für superskalare Prozessoren: Latenzzeiten werden ca. mit Länge des issue packets skaliert
- „Längere“ Verzögerung (in Anzahl Befehlen) für Load/Stores bzw. Branches
- Lösung: Erweiterung des Tomasulo-Algorithmus auf Multiple-Issue durch
- Sequentielles Ausgeben mehrerer Befehle an Reservation Stations innerhalb eines Taktes, oder
- „Verbreiterung“ der Ausgabe-Logik (issue logic) zur Behandlung mehrerer Operationen parallel
- (alle Abhängigkeiten gleichzeitig überprüfen!)
### VLIW - Very Long Instruction Word
VLIW (Very Long Instruction Word)-Prozessor
- verschiedene parallele Ausführungseinheiten
- Verteilung von Maschinencode direkt vom Befehlswort im Speicher vorgegeben
- Sieht für jede Ausführungseinheit dezidierte Anweisungen vor
- keine Abhängigkeiten daher geringere Komplexität in Hardware
- Meist für stark parallelisierbare Aufgaben verwendet (Signalverarbeitung, Vektorrechner, DSP)
- Vorteile:
- Die parallele Architektur des Prozessors kann schon während der der Programmerstellung (Kompilieren) zur Optimierung genutzt werden.
- Keine aufwendige Prozessorhardware zur Befehlsverteilung/Abhängigkeitsanalyse erforderlich (einfacherer Prozessor)
- Ausführungszeiten sind im wesentlichen bekannt
- Nachteile:
- Aufwendigere Compiler
- Schlechte Prozessorauslastung bei ungünstigem Code
- Rekompilierung für den Prozessor erforderlich (kein Universalrechner)
- Größerer Speicherbedarf (Programm), wenn Code nicht parallelisiert werden kann.
- Direkt abgebildet (Direct mapping): Für caching von Befehlen besonders sinnvoll, weil bei Befehlen Aliasing sehr unwahrscheinlich ist
- Satz-assoziativ abgebildet (Set-associative mapping): Sehr häufige Organisationsform, mit Set-Größe = 2, 4 oder 8
- Vollassoziativ abgebildet (Associative mapping): Wegen der Größe moderner Caches kommt diese Organisationsform kaum in Frage
- Ersetzungs-Strategien
- Zufallsverfahren: Hier wird der zu ersetzende Block innerhalb des Satzes zufällig ausgewählt.
- FIFO-Verfahren: Beim FIFO-Verfahren (engl. First In, First Out) wird der älteste Block ersetzt, auch wenn auf diesem gerade erst noch zugegriffen wurde
- LRU-Verfahren: Beim LRU-Verfahren (engl. least recently used ) wird der Block ersetzt, auf den am längsten nicht mehr zugegriffen wurde
- LFU-Verfahren: Beim LFU-Verfahren (engl. least frequently used ) wird der am seltensten gelesene Block ersetzt
- CLOCK-Verfahren: Hier werden alle Platzierungen gedanklich im Kreis auf einem Ziffernblatt angeordnet. Ein Zeiger wird im Uhrzeigersinn weiterbewegt und zeigt den zu ersetzenden Eintrag an.
Schreibverfahren: Strategien zum Rückschreiben Cache → (Haupt-) Speicher
- Write-Through (Durchschreiben):
- Jeder Schreibvorgang in den Cache führt zu einer unmittelbaren Aktualisierung des (Haupt-) Speichers
- Speicher wird Engpass, es sei denn, der Anteil an Schreiboperationen ist klein oder der (Haupt-) Speicher ist nur wenig langsamer als der Cache.
- Copy-Back, conflicting use write back
- Rückschreiben erfolgt erst, wenn Cache-Zeile bei Miss verdrängt wird
- Funktioniert auch bei großen Geschwindigkeitsunterschieden zwischen Cache und Speicher. Vorkehrungen erforderlich, damit keine veralteten Werte aus dem Speicher kopiert werden.
![Verbindungsnetzwerke; Quelle RA2 Vorlesung 2020/21](Assets/RA2_Verbindungsnetzwerke.png)
![Verbindungsnetzwerke2; Quelle RA2 Vorlesung 2020/21](Assets/RA2_Verbindungsnetzwerke2.png)
Dual-Core-System mit mehrstufiger Bushierarchie
![Dual Core System; Quelle RA2 Vorlesung 2020/21](Assets/RA2_DualCoreSystem.png)
Reales Shared Memory System
![Shared Memory System; Quelle RA2 Vorlesung 2020/21](Assets/RA2_SharedMemorySystem.png)
Cache(daten)-Kohärenz
- Daten-Kohärenz
- Sagt aus, welcher Wert beim Lesen abgeliefert wird
- Bezug auf Lesen und Schreiben ein- und derselben Speicherzelle
- Definition: Ein Speichersystem heißt kohärent, wenn
- bei einem Schreiben einer Zelle x durch einen Prozessor, welches von einem Lesen derselben Zelle gefolgt wird, das Lesen immer den geschriebenen Wert abliefert, sofern zwischen beiden Operationen kein Schreiben eines anderen Prozessors erfolgt;
- Bei einem Schreiben einer Zelle x durch einen Prozessor P, welches von einem Lesen derselben Zelle durch einen Prozessor P’ gefolgt wird, das Lesen immer den geschriebenen Wert abliefert, sofern zwischen beiden Operationen kein Schreiben eines anderen Prozessors erfolgt und sofern zwischen beiden Operationen hinreichend viel Zeit vergeht;
- Schreibvorgänge in die selbe Zelle serialisiert werden, d.h. zwei Schreibvorgänge durch zwei Prozessoren werden durch die übrigen Prozessoren in derselben Reihenfolge gesehen.
- Beispiel 1:
- Variable X befindet sich in den Caches von P1, P2 und im Hauptspeicher: kohärente Ausgangssituation
![Cache Kohärenz Beispiel; Quelle RA2 Vorlesung 2020/21](Assets/RA2_CacheKohärenz.png)
- P1 schreibt X = 1 in den Cache und in den Hauptspeicher
- P2 liest alten Wert aus Cache: inkohärentes Ergebnis
- Beispiel 2:
- Variable X befindet sich im Cache von P1 und im Hauptspeicher: kohärente Ausgangssituation
- P1 schreibt X = 1 nur in den Cache
- P2 liest alten Wert aus Hauptspeicher: inkohärentes Ergebnis
- Beispiel 3:
- Kohärente Ausgangssituation
- Einlesen mittels Direct Memory Access (DMA)
- P2 liest alten Wert aus Cache: inkohärentes Ergebnis
- Beispiel 4:
- Kohärente Ausgangssituation
- P1 modifiziert X im Copy-Back Cache
- Inkonsistente Daten werden ausgegeben
- Lösung des I/O-Problems
- Zuordnung einer I/O-Einheit zu jedem Prozessor
![Cache I/O Einheit; Quelle RA2 Vorlesung 2020/21](Assets/RA2_CacheIOEinheit.png)
- Hardware-Lösung (I/O-Problem): Aufwändig, schlechte Lokalität der Daten
- Gemeinsamer Cache für alle Prozessoren: Hoher Hardware-Aufwand, geringe Effizienz
- Unterscheidung in cacheable und non-cacheable Daten: Hoher Aufwand (Programmierer, Compiler)
- Cache-Kohärenzprotokolle
- Snooping-Protokolle
- Directory-Protokolle
Snooping-Protokolle
- Die Caches aller Prozessoren beobachten alle Datenübertragungen von jedem Cache zum Hauptspeicher.
- Alle anderen Prozessoren aktualisieren den Cache-Block
Write-Through - Write Invalidate
![WriteInvalidate; Quelle RA2 Vorlesung 2020/21](Assets/RA2_WriteInvalidate.png)
Copy-Back
- Problem: Copy-Back Caches führen zur temporären Inkonsistenz
- Lösung: exklusives Eigentumskonzept durch Zustandsgraph pro Cache-Block
- MESI (Modified, Exclusive, Shared, Invalid)
- Mischung zwischen Write-Through und Copy-Back
MESI:
- Vier Zustände
- **(exclusive) Modified**: Cache-Block wurde lokal geändert, die Kopie im Hauptspeicher ist ungültig. Will ein anderer Prozessor dieses Datum im Hauptspeicher lesen, so muss der Cache-Block erst in den Hauptspeicher zurückgeschrieben werden.
- **Exclusive (unmodified)**: Dieser Cache ist der einzige, der den Cache-Block enthält, Wert im Hauptspeicher ist gültig. Liest ein anderer Prozessor dieses Datum im Hauptspeicher, so muss die Zeile als shared markiert werden. Wird das Datum im Hauptspeicher verändert, ist der Cache-Block auf invalid zu setzen.
- **Shared (unmodified)**: Mehrere Caches (mind. 2) enthalten dieses Datum. Da alle bisher nur gelesen haben, ist das Datum im Hauptspeicher gültig. Schreibzugriffe auf einen shared Cache-Block müssen immer zu einer Bus-Operation führen, damit die Cache-Blocks der anderen Caches auf invalid gesetzt werden können.
- **Invalid**: Cache-Block ist noch gar nicht geladen bzw. veraltet/ungültig
- Prozessoren können auf einen Speicherblock lesend oder schreibend zugreifen. Lese- und Schreiboperationen von Prozessoren lösen Operationen auf dem Bus aus.
- Bus-Operationen
- **Bus Read**: wenn ein Prozessor Wert eines Speicherblocks lesen will
- **Bus Read Exclusive**: wenn ein Prozessor Wert eines Speicherblocks überschreiben will
- **Flush**: wenn ein Prozessor $P_i$ einen Speicherblock alleinig in seinem Cache hat, ein anderer Prozessor $P_j$ aber lesend oder schreibend auf diesen Block zugreift. Bei einer Flush-Operation legt $P_i$ ebenfalls das Datum des Speicherblocks auf den Bus.
- Steuersignale
- **Invalidate-Signal**: Invalidieren des Blocks in den Caches anderer Prozessoren
- **Shared-Signal**: Signalisierung, ob ein zu ladendes Datum bereits als Kopie im Cache vorhanden ist
- **Retry-Signal**: Aufforderung von Prozessor $P_i$ an Prozessor $P_j$, das Laden eines Datums vom Hauptspeicher abzubrechen, da der Hauptspeicher noch ein altes, ungültiges Datum besitzt und vorher aktualisiert werden muss. Das Laden durch $P_j$ kann danach wiederholt werden.
- ![MESI Protokoll; Quelle RA2 Vorlesung 2020/21](Assets/RA2_MESI-Protokoll.png)
- ![Zustände; Quelle RA2 Vorlesung 2020/21](Assets/RA2_MESI-Zustände.png)
- ![Bedingungen; Quelle RA2 Vorlesung 2020/21](Assets/RA2_MESI-Bedingungen.png)
- Bewertung von Snooping-Protokollen
- Leichte Implementierbarkeit bei Bus-basierten Shared Memory Systemen
- Snooping skaliert bei Bussen jedoch nicht
- Bei vielen beteiligten Prozessoren sinkt die effektive Bandbreite des Busses, da überproportional viele Invalidierungsnachrichten per Broadcast über den Bus gehen
- Punkt-zu-Punkt Netzwerke sind skalierbar, jedoch ist die Implementierung von Broadcasts hier aufwändig
- Für Snooping-Protokolle daher oft ungeeignet
Directory-Protokolle
- Beobachtung
- Nur wenige Prozessoren teilen sich die gleichen Daten in vielen Anwendungen
- Kenntnis nur dieser Prozessoren ist nötig
- Directory-Protokolle
- Directory-Protokolle nutzen Lokalitätsinformationen, um die Anzahl an Invalidierungsnachrichten zu minimieren
- Nachrichten gehen nur an Prozessoren, die eine Kopie des Cache-Blocks besitzen
- Directory-Protokolle skalieren daher auch für Netze ohne Broadcast-Fähigkeit
- Ansatz: Presence Flag Vector
- Im Hauptspeicher abgelegter Bit-Vektor für jeden einzelnen Speicherblock:
- 1 Bit pro Prozessor/Cache + Statusbits (dirty, modified)
- Bewertung von Directory-Protokollen
- Problem: Wachstum des Speicherbedarfs linear mit Anzahl der Prozessoren
- Beispiel: Speicherblöcke von 64 Bytes Größe
- 64 Prozessoren = Overhead 12,69%
- 256 Prozessoren = Overhead 50,2%
- 1024 Prozessoren = Overhead 200,16%
Multiprozessor-Konfiguration eines Hochleistungssystems
![Multiprozessor-Konfiguration eines Hochleistungssystems; Quelle RA2 Vorlesung 2020/21](Assets/RA2_MultiprozessorHochleistungssystem.png)
IBM Blue Gene/L
![Knoten; Quelle RA2 Vorlesung 2020/21](Assets/RA2_BlueGeneKnoten.png)
![Architektur; Quelle RA2 Vorlesung 2020/21](Assets/RA2_BlueGeneArchitektur.png)