Grundlagen der Rechnerarchitektur
Speicher
Übersicht
• Speicherhierarchie
• Cache‐Grundlagen
• Verbessern der Cache‐Performance
• Virtueller Speicher
Speicherhierarchie
Ein großer und schneller Speicher?
• Besonders schnelle Speicher sind besonders teuer
• Schnellste Speicher müssen auch nahe am Prozessor sein.
Speichertechnologie Typische Zugriffszeiten $ per GB in 2008
SRAM 0,5‐2,5 ns $2000‐$5000
DRAM 50‐70 ns $20‐$75
Magnetic Disk 5.000.000‐20.000.000 ns $0,2‐$2
Beispiel: Signalausbreitungsgeschwindigkeit von etwa 0,3 * 109 m/s und Zugriffszeit von 500 ps ergibt eine Distanz von 15 cm.
Brauchen wir immer den gesamten Speicher?
• Das Lokalitätsprinzip
– Zeitliche Lokalität – Räumliche Lokalität
• Beispiel: wir schreiben ein Referat in der Bibliothek
• Beispiel: typisches Verhalten von Programmen
– Schleifen fördern zeitliche Lokalität
– Sequentielle Abarbeitung fördert räumliche Lokalität
• Sequentielle Abarbeitung von Instruktionen
• Iterativer Zugriff auf Daten; z.B. Array‐ oder Record‐Elemente
Idee: Speicherhierarchie
• Das Bild ist ein Beispiel; was ist z.B. mit Flash‐RAM?
Terminologie
• Cache
• Caches werden meist mit ihrer Größe benannt; 4KB‐Cache
• Block (oder auch Line genannt)
• Hit und Miss
• Hit‐Rate und Miss‐Rate
• Hit‐Time und Miss‐Penalty
• Offensichtlich: Hit‐Time << Miss‐
Penalty
(Begriffe sind unabhängig von dem konkreten Level)
Zusammengefasst
Cache‐Grundlagen
Cache‐Grundlagen
Lesender Cache‐Zugriff
Beispiel: Cache vor und nach einem Miss
• Was macht die CPU während eines Cache‐Miss? CPU‐Stall.
• Im folgenden beantworten wir die folgenden Fragen:
– Wie stellt man fest, ob Xn im Cache ist?
– Wie findet man Xn überhaupt in dem Cache?
Mögliche Lösung: Direct‐Mapped‐Cache
Beispiel: Speicher mit 32 und Cache mit 8 Einträgen
Problem: Speicherbereiche überlappen
Lösung: Tags (markiere Cache‐Eintrag mit oberem Teil der Adresse) Beispiel: Adresse 10001 ergibt Cache‐Index 001 und Tag 10.
Tag|Index ergibt wieder 10001
Problem: ist der Cache‐Eintrag gültig?
Ein Beispiel
Index Valid Tag Daten 000
001 010 011 100 101 110 111
Adresse des Zugriffs Daten Hit oder Miss
10110 42
00011 4711
10110 42
11110 50
Cache‐Blöcke und Offsets
Ein Cache‐Eintrag speichert in der Regel gleich mehrere im Speicher aufeinander folgende Bytes.
Grund: räumliche Lokalität wird wie folgt besser ausgenutzt:
• Bei Cache‐Miss gleich mehrere Bytes laden
• Anschließende Zugriffe auf benachbarte Bytes sind dann ein Hit Konsequenz auf die Aufteilung der Adresse der Form Tag|Index?
Tag Index Offset
Beispielimplementierung eines 4KB‐Cache
Quiz
Gegeben sei ein 16KB‐Cache mit 32 Byte Blockgröße.
Wie verteilen sich die Bits einer 32‐Bit‐Adresse auf:
Tag Index Byte‐Offset
32‐Bit‐Adresse
31 30 29 ... 2 1 0
Quiz
Gegeben sei ein Cache mit 64 Blöcken mit Block‐Größe 16 Bytes.
Was ist die Cache‐Größe in KB?
Wie groß sollten Cache‐Blöcke sein?
• Je Länger die Blöcke desto größer die Konkurrenz.
Ergänzung: Split‐Caches
Split‐Cache: besteht aus zwei unabhängigen Caches
• Ein Cache für die Instruktionen
• Ein Cache für die Daten
Vorteil: die Cache‐Bandbreite (d.h. wie viel Daten pro Zeiteinheit können ausgelesen/geschrieben werden) wird erhöht.
Erinnerung: unsere MIPS‐CPU konnte auch gleichzeitig einen Instruction‐Fetch und einen Datenzugriff machen.
Nachteil: die Miss‐Rate erhöht sich, da die Aufteilung in Bytes für Instruction‐ und Daten‐Cache fest ist und ggf. nicht optimal für das aktuelle Programm ist.
Beispiel: Miss‐Raten für einen Intrinsity FastMATH Prozessor
• Split‐Cache (32 KB aufgeteilt): 3,24% Miss‐Rate
• Combined‐Cache (32 KB für einen Cache): 3,18% Miss‐Rate
Cache‐Grundlagen
Schreibender Cache‐Zugriff
Eine einfache Strategie
• Schreibt man nur in den Cache, werden Cache und darunter liegender Speicher inkonsistent. Wie erreicht man Konsistenz?
• Write‐Through
– Schreibe immer sofort in den Speicher zurück – Einfach aber schlechte Performance
Beispiel: 10% Store‐Instruktionen, CPI ohne Miss = 1 und
zusätzlicher CPI bei Speicherzugriff = 100. Was ist der Gesamt‐CPI‐
Wert?
Verbesserungen
• Write‐Buffer
– Ergänzung zu Write‐Through
– Ausstehende Writes werden in einem kleinen Puffer zwischengespeichert – CPU kann nach schreiben in den Puffer sofort weiter machen
– Parallel werden Daten aus dem Puffer in den Speicher geschrieben – CPU muss nur stallen, wenn der Puffer voll ist.
• Write‐Back
– Alternative zu Write‐Through
– Speichere Änderungen zunächst nur im Cache
– Schreibe Änderung in Speicher nur dann, wenn der Cache‐Block ersetzt wird
Behandlung von Cache‐Misses
• Was passiert beim Schreiben (sowohl bei Write‐Through als auch Write‐Back) eines Bytes bei einem Cache‐Miss?
• Eine naheliegende Lösung
– Lade den gesamten Block aus dem Speicher – Überschreibe das Byte in dem Block
• Alternative: No‐Write‐Allocate
– Aktualisiere nur den darunter liegenden Speicher aber nicht den Cache – Ist sinnvoll, wenn lesender Zugriff nicht zu erwarten ist
Cache‐Grundlagen
Speicherunterstützung für Caches
Motivation
Erinnerung: CPU und Speicher kommunizieren über einen Bus.
Was beeinflusst die Miss‐Penalty?
• Geschwindigkeit des Busses.
• Speicherorganisation (siehe gleich).
Ein angenommenes Beispiel von Speicherzugriffswerten:
• 1 Speicherbuszyklus die gewünschten Adressen zu senden
• 15 Speicherbuszyklen für jeden initiierten DRAM‐Zugriff
• 1 Speicherbuszyklus ein Datenwort zu senden
Was ist die Miss‐Penalty bei einem Cache mit vier Word Breite und sequentiellem Zugriff auf ein DRAM mit einem Word Breite?
Kann man das verbessern?
Bessere Unterstützung durch das DRAM
Was ist die Miss‐Penalty für zweimal breiteren Bus und Speicher?
Bezeichnet man auch als Interleaving.
Bessere Unterstützung durch das DRAM
Was ist die Miss‐Penalty für Speicherorganisation mit 4 parallelen Bänken aber unverändertem Bus?
Bezeichnet man auch als Interleaving.
Entwicklungen der letzten Jahre
Organisation des Speichers in Zeilen und Spalten.
Vorhalten einer ganzen Zeile in einem schnelleren RAM‐internen SRAM.
Verbessern der Cache‐Performance
Verbesserte Cache Strategien
Im Folgenden betrachten wir eine Verbesserung von Direct‐
Mapped‐Caching.
Zur Darstellung der Verbesserung verwenden wir folgende vereinfachte Cache‐Darstellung:
Tag Data 0
1 2 3 4
Speicher‐Blöcke 0 : ...
1 : ...
2 : ...
. .
Fully‐Associative‐Cache
Beobachtung: bei Direct‐Mapped‐
Cache kann ein Speicherblock nur an einer Stelle gespeichert werden.
Konsequenz: wechselhafter Zugriff auf zwei Speicherblöcke die auf die selbe Stelle gemappt werden, führt
permanent zu Cache‐Misses.
Praktisch wäre doch folgender Cache:
Ein Eintrag kann überall stehen.
Nachteil: Durchsuchen des Cache dauert länger und mehr Hardware‐Aufwand! Wie wäre es mit einem Kompromiss: ...
Tag Data 0
1 2 3 4 5 6 7
Speicher‐Blöcke 0 : ...
1 : ...
2 : ...
. .
8 : ...
9 : ...
10 : ...
.
Tag Data Tag Data Tag Data Tag Data Tag Data Tag Data Tag Data Tag Data
(N‐Wege)‐Set‐Associative‐Cache
Tag Data 0
1 2 3 4 5 6 7
Direct‐Mapped
Set Tag Data Tag Data
0 1 2 3
Set Tag Data Tag Data Tag Data Tag Data
0 1
Two‐Way‐Set‐Associative Speicher‐Blöcke
0 : ...
1 : ...
2 : ...
. .
8 : ...
9 : ...
10 : ...
.
Zwischenbilanz
Finden der Cache‐Zeile c des Speicher‐Blocks n in einem Direct‐
Mapped‐Cache der Größe k?
(Vergleiche anschließend n mit dem in Zeile c gespeicherten Tag)
Finden der Set s des Speicher‐Blocks n in einem N‐Way‐Set‐
Associative‐Cache mit k Sets?
(Durchlaufe dann die Set s und suche nach einem Tag der n entspricht)
Eine Frage ist noch zu klären
Annahme die Set eines N‐Way‐Set‐Associative‐Cache ist voll (bzw.
der Fully‐Associative‐Cache ist voll). Wo kann ein neuer Speicherblock abgelegt werden?
Tag Data Tag Data Tag Data Tag Data
24 ... 66 ... 20 ... 16 ...
Tag Data 44 ...
???
Mehr Wege resultieren in weniger Misses
Beispiel: betrachte Cache‐Varianten mit vier Speicherblöcken
Wie viele Cache‐Misses erzeugt die folgende Sequenz von Speicherblockzugriffen?
0 , 8 , 0 , 6 , 8
Tag Data Tag Data Tag Data Tag Data Tag Data
0 1 2 3
Set Tag Data Tag Data 0
1
Direct‐Mapped Set‐Associative Fully‐Associative
Mehr Wege resultieren in weniger Misses
Beispiel: Direct‐Mapped
Speicherblockzugriffe: 0 , 8 , 0 , 6 , 8 (Speicherblockinhalt = M[i])
Tag Data 0
1 2 3
Zugriff Hit oder Miss
Inhalt der Cache‐Blöcke nach der Referenz
0 1 2 3
0 8
Block‐Adresse Cache‐Block 0
6 8
Vorüberlegung: Auf welchen Cache‐Block werden die Block‐Adressen gemapped?
Mehr Wege resultieren in weniger Misses
Beispiel: Set‐Associative
Speicherblockzugriffe: 0 , 8 , 0 , 6 , 8 (Speicherblockinhalt = M[i])
Zugriff Hit oder Miss
Inhalt der Cache‐Blöcke nach der Referenz Set 0 Set 0 Set 1 Set 1 0
8 0 6 8
Block‐Adresse Cache‐Set 0
6 8
Vorüberlegung: In welche Set werden die Block‐Adressen gemapped?
Set Tag Data Tag Data 0
1
Mehr Wege resultieren in weniger Misses
Beispiel: Fully‐Associative
Speicherblockzugriffe: 0 , 8 , 0 , 6 , 8 (Speicherblockinhalt = M[i])
Zugriff Hit oder Miss
Inhalt der Cache‐Blöcke nach der Referenz Block 0 Block 1 Block 2 Block 3 0
8
Tag Data Tag Data Tag Data Tag Data
Wie Aufwendig sind mehr Wege?
Offset 2 Bits
Wie viele Wege sind sinnvoll?
Feste Zahl kann hier nicht genannt werden. Tradeoff:
Zeit/Hardware‐Aufwand versus Miss‐Raten.
Beobachtung:
(64KB Cache, 16‐Word‐Blöcke)
CPU
Multi‐Level‐Caches
First‐Level‐Cache
Second‐Level‐Cache
Speicher
Optimiert auf geringe Hit‐Time (und damit
recht klein)
Optimiert auf geringe Miss‐Ratio (also mehr und größere Blöcke und
damit höhere Hit‐Time)
Virtueller Speicher
Die Idee
Speicherblock 0
Virtuelle Adressen
Speicherblock 1 Speicherblock 2 Speicherblock 3 Speicherblock 4 Speicherblock 5 Speicherblock 6 Speicherblock 7
...
Speicherblock n Prozess 1
Speicherblock 0
Virtuelle Adressen
Speicherblock 1 Speicherblock 2 Speicherblock 3 Speicherblock 4 Speicherblock 5 Speicherblock 6 Speicherblock 7
...
Speicherblock n Prozess 2
Speicherblock 0 Speicherblock 1 Speicherblock 2 Speicherblock 3 Speicherblock 4 Speicherblock 5
...
Speicherblock m
Virtueller Speicher Sekundärer Speicher Virtueller Speicher (Festplatte oder SSD)
Physikalischer Speicher Address‐
Translation
Address‐
Translation
Abbilden von virtuellen auf physikalische Adressen
Virtuelle Seitennummer Seiten‐Offset
Translation
Physikalische Seitennummer Seiten‐Offset
31 30 29 28 27 ... 15 14 13 12 11 10 9 8 ... 3 2 1 0 Virtuelle Adresse
29 28 27 ... 15 14 13 12 11 10 9 8 ... 3 2 1 0 Physikalische Adresse
Quiz: Größe x des virtuellen Adressraumes, Größe y des physikalischen Adressraumes und
Weitere Details zur Address‐Translation
Page‐Faults
Page‐Fault: die Page muss in eine freie Page im Speicher geladen werden. Was, wenn keine Page mehr frei ist?
Andere Page im Speicher muss ausgelagert werden. Mögliche Ersetzungsstrategie: LRU (siehe voriges Thema Caching).
Woher weiß man eigentlich, welche Page schon lange nicht mehr adressiert wurde?
Manche Prozessoren können die Page‐Table mit einem
Reference/Use‐Bit taggen. Den Rest muss das Betriebssystem
Wie groß ist die Page‐Table?
Im vorigen (typischen) Beispiel verwenden wir 20 Bits zum
indizieren der Page‐Table. Typischerweise spendiert man 32 Bits pro Tabellenzeile (im Vorigen Beispiel brauchten wir mindestens 18
Bits). Damit benötigen wir insgesamt:
Anzahl Page‐Table‐Einträge:
Größe der Page‐Table:
Wir benötigen so eine Page‐Table pro Prozess!
Noch gravierender ist es natürlich für 64‐Bit‐Adressen!
Größe der Page‐Table:
Techniken zur Reduktion der Page‐Table‐Größe
Page‐Table‐Größe ist limitiert durch ein spezielles Limit‐Register:
Adressen erst mal nur bis maximal dem Inhalt des Limit‐Registers erlaubt. Limit‐Register wird nur bei Bedarf (also überschreiten) erhöht. Sinnvoll, wenn Speicher nur in eine Richtung wächst.
Page‐Table ist in zwei Segmenten organisiert:
Beide Segmente wachsen wie vorhin beschrieben mittels eines Limit‐
Registers nur bei Bedarf. Ein Segment wird für den Stack verwendet und wächst von oben nach unten. Das andere Segment wird für den Heap verwendet und wächst von unten nach oben. Höchstes Adress‐
Bit bestimmt welches der beiden Segmente verwendet wird. (Also:
Techniken zur Reduktion der Page‐Table‐Größe
Invertierte Page‐Tables:
Es wird eine Hash‐Funktion auf die virtuelle Adresse angewendet.
Die Größe der Page‐Table entspricht der Anzahl Seiten im
physikalischen Speicher. Jeder Eintrag speichert die aktuellen High‐
Order‐Bits der Adressen zu den die aktuelle Page gehört.
Mehrere Level von Page‐Tables:
Oberster Level zeigt zunächst auf sehr große Blöcke (auch als
Segmente bezeichnet). Innerhalb eines Segments wird wiederum mittels Page‐Table feiner (dann als Pages bezeichnet) unterteilt.
Referenzieren einer Page: High‐Order‐Bits bestimmen das Segment (wenn vorhanden); die nächsten Bits dann die richtige Page in
diesem Segment. Nachteil dieses Verfahrens: Adress‐Translation ist aufwendiger.
Techniken zur Reduktion der Page‐Table‐Größe
Paged‐Page‐Tables:
Page‐Table befindet sich selber im virtuellen Speicher. Mögliche rekursive Page‐Faults müssen durch geeignete Betriebssystem‐
Mechanismen verhindert werden. (Keine weiteren Details hier)
Schreiben von Pages
Schreiben einer Page in den Swap‐Space ist sehr teuer (kostet millionen von CPU‐Zyklen).
Write‐Through‐Strategie (siehe Abschnitt über Caching) ist hier
somit nicht sinnvoll. Eine sinnvolle Strategie ist Write‐Back, d.h. nur, wenn die Seite von einer anderen in den Swap‐Space verdrängt
wird, wird diese auch in den Swap‐Space geschrieben.
Auch das ist immer noch gleich so teuer, kommt aber seltener vor.
Muss man eine verdrängte Seite eigentlich immer zurückschreiben?
Nur, wenn diese verändert wurde.
CPU muss bei jedem schreibenden Zugriff auf eine Page in der Page‐
Table ein Dirty‐Bit setzen.
Beobachtung für jeden Speicherzugriff
Virtueller Speicher ist aufwendiger als direkter physikalischer Zugriff
Der Translation‐Lookaside‐Buffer (TLB)
Protection mittels virtuellem Speicher
Virtueller Speicher erlaubt, dass mehrere Prozesse auf denselben physikalischen Speicher zugreifen.
Es ist unter Umständen sinnvoll, den Speicherbereich vor Schreibzugriff zu schützen.
TLB und Page‐Table speichern ein extra RW‐Bit.
(1) Wer setzt dieses RW‐Bit? (2) Wie setzt man dieses Bit?
Zu (1): Ein Betriebssystem‐Prozess.
Zu (2): Einfache Maschineninstruktionen?
Problem: Jeder kann dann das Bit setzen.
Betriebsmodi einer CPU
Häufig zwei unterschiedliche Betriebsmodi:
• Normaler Betriebsmodus
• Kernel‐ (oder auch Supervisor)‐Mode
CPU erlaubt die Ausführung bestimmter Maschinen‐Instruktionen nur im Kernel‐Mode.
Page‐Tables werden im physikalischen Speicher abgelegt, auf den kein anderer virtueller Adressraum zeigt.
Wie erreicht man den Kernel‐Mode? Es muss verhindert werden, dass jeder die CPU in diesen Modus versetzen kann.
Üblicher Weg: System‐Call.
Erinnerung: damit kann man eine Betriebssystemfunktion aufrufen.
Mit System‐Call wird eine Exception ausgelöst und an eine
Speicherstelle gesprungen, die nur in Kernel‐Mode zugreifbar ist.
Was passiert bei einem Page‐Fault noch?
Aktueller Prozess kann die Instruktion, die den Page‐Fault ausgelöst hat, nicht weiter ausführen.
Betriebssystem kann einem anderen Prozess die CPU zur Verfügung stellen.
Sobald die Page geladen ist, kann dem ursprünglichen Prozess die CPU wieder zur Verfügung gestellt werden.
Hierzu muss der ursprüngliche Prozesskontext wieder hergestellt werden; unter anderem natürlich der PC auf die Instruktion gesetzt
Segmentierung – Motivation
Bisher haben wir feste Blockgrößen betrachtet. Ziel: Paging stellt
dem Anwender einen großen (eindimensionalen) Speicher von 0 bis 2b‐1 (b = Bit‐Tiefe) bereit.
Annahme Programm benötigt mehrere Speicherbereiche deren Längen im Programmablauf variabel sind. Beispiel Compiler:
Für solche Anwendungsfälle ist es besser dem Anwender sichtbar mehrere unabhängige Speicherbereiche zur Verfügung zu stellen.
Symbol‐
tabelle
Source‐
Code
Kon‐
stanten
Parse‐
Tree Call‐Stack
0 … A … B … C … D … E … 2b‐1
Segmentierung ‐ Grundidee
Voriges Beispiel Compiler:
Dieses Konzept mit variablen Blockgrößen nenn man Segmentierung.
Im Gegensatz zu Paging: explizit sichtbare zweidimensionale Adressierung (n,k) mit Segment‐Nummer n und Segment‐Offset k
• Anfang kann auf einen beliebigen Startpunkt im Speicher zeigen.
Symbol‐
Tabelle Source‐
Code
Kon‐
stanten
Parse‐
Tree Call‐
Stack
0K 4K 8K 12K 16K 20K 24K
0K 4K 8K 12K 16K
0K 4K
0K 4K 8K 12K 16K 20K
0K 4K 8K 12K
Implementierung über Segment‐Tabelle
Segment‐Nummer
(Selector) Offset
Basis‐Adresse Limit
Andere Felder (z.B.
Priviledge, Protection,…) Adressierung im virtuellen Addressraum
Eintrag in Segmenttabelle Segmenttabelle
+
N‐Bit lineare Adresse
Damit geeigneter Zugriff auf physikalischen Speicher
Segmentierung versus Paging
Paging Segmentierung
Für den Programmierer sichtbar Nein Ja
Anzahl verfügbarer linearer Adressbereiche
1 Viele
Mehr als der physikalische Speicherbereich verfügbar
Ja Ja
Trennung von Programm und Daten mit unterschiedlichem Protection möglich
Nein Ja
Unterstützung mehrerer
Speicherbereiche mit dynamischer Größe
Nein Ja
Unterstützung von Code‐Sharing Nein Ja
Motivation für die
Einführung/Verwendung
Bereitstellung eines großen Adressraumes
Trennung von Programm und Daten in logische
Pure Segmentierung: Jedes Segment belegt ab einer Basisadresse einen aufeinander‐
folgenden physikalischen Speicherbereich. (z.B. Ausgangspunkt (a)) Mit der Zeit entsteht eine sog. externe Fragmentierung (z.B. (b), (c), (d)) Mögliche Lösung: Compactation (z.B. (e))
Problem mit purer Segmentierung
Segment 0 (4K) Segment 1
(8K) Segment 2
(5K) Segment 3
(8K) Segment 4
(7K)
Segment 0 (4K) Segment 7
(5K) Segment 2
(5K) Segment 3
(8K) Segment 4
(7K)
Segment 0 (4K) Segment 2
(5K) Segment 3
(8K) Segment 5
(4K)
(3K)
(3K)
Segment 7 (5K) (3K)
Segment 0 (4K) Segment 2
(5K) Segment 6
(4K) Segment 5
(4K) (3K)
Segment 7 (5K) (3K) (4K)
Segment 0 (4K) Segment 2
(5K) Segment 6
(4K) Segment 5
(4K) (10K)
Segment 7 (5K)
(a) (b) (c) (d) (e)
Lösung: Segmentierung mit Paging (1)
Beispiel Intel Pentium:
• Es gibt zwei Segment‐Tabellen (mit 8K+8K Einträgen)
• GDT (Global Descriptor Table) – eine globale Tabelle für alle Prozesse
• LDT (Local Descriptor Table) – für jeden Prozess eine individuelle Tabelle
• Es gibt 6 sog. Segment‐Register
(u.a. CS als Selector für Code und DS als Selector für Daten)
• Selector‐Format 16‐Bit
Index 0=GDT1=LDT Level (0‐3)Privilege‐
Lösung: Segmentierung mit Paging (2)
Beispiel Intel Pentium:
• Aufbau eines Segment‐Descriptors (8 Bytes)
• Base: 32‐Bit‐Basis‐Adresse des Segments (Format bzgl. Base und Limit ist Downward‐
Kompatibilität mit 24‐Bit‐Base des 286 geschuldet)
• (Privilege Level, Segement‐Type und Protection siehe gleich)
• Limit: mittels Granularity‐Bit entweder in Bytes (max. Segmentgröße 220=1MB) oder in 4K‐Pages (max. Segmentgröße 4K*220=4GB)
• Damit zunächst also: Zugriff auf physikalischen Speicher mittels Basis‐Adresse plus Offset (Segemente dürfen sogar überlappen)
• Wo ist denn Paging als Lösung angewendet???
Lösung: Segmentierung mit Paging (3)
Beispiel Intel Pentium:
• Mittels Bit in globalem Control‐Register kann man Paging dazuschalten
• Lineare Adresse wird dann nicht direkt als physikalische Adresse verwendet
• Stattdessen wird die Adresse als virtuelle Adresse des Pagings verwendet
• Virtuelle 32‐Bit‐Adresse: es wird zweistufiges Paging verwendet
Dir Page Offset
Lineare Adresse
Zum Abschluss: Protection
Beispiel Intel Pentium:
• Vier Protection Level (0 bis 3; Level 0 hat höchste Privilegien)
• Zu jedem Zeitpunkt befindet sich ein Programm in einem der Level
• Jedes Segment ist ebenfalls einem Level zugeordnet.
• Unmittelbarer Zugriff auf Segment nur aus gleichem Level oder aus Level mit höheren Privilegien möglich; ansonsten Trap/Exception!
• Aufruf von Prozeduren ist aber auf kontrollierte Weise über call‐Instruktion möglich
• call verwendet anstatt Adresse einen Segment‐Selector
• Dieser beschreibt einen sogenannten call‐Gate (welcher die Aufrufadresse festlegt)
• Damit Sprung an beliebige Stelle nicht möglich; nur offizielle Eintrittspunkte können verwendet werden
• Typisches Beispiel (siehe Grafik)
• Type‐Feld wird zur Unterscheidung
zwischen Code‐Segment, Daten‐Segment und verschiedene Typen von Gates
verwendet
Parallelität und Caches
Cache‐Kohärenz‐Problem
CPU 1 (oder Core 1) Cache
CPU 2 (oder Core 2) Cache
Speicher
Zeitschritt Event Cache‐Inhalt für CPU 1
Cache‐Inhalt für CPU 2
Speicherinhalt für Adresse X
0 0
1 CPU 1 liest X 0 0
2 CPU 2 liest X 0 0 0
3 CPU 1 speichert 1 nach X
1 0 1
Wann gilt ein Cache als kohärent?
1. Lesen von Speicherstelle X nach schreiben in Speicherstelle X sollte den geschriebenen Wert zurück geben, wenn kein
weiterer Prozess auf die Stelle X geschrieben hat.
2. Nachdem ein Prozess in Speicherstelle X geschrieben hat, sollte
„nach einer gewissen Zeit“ jeder Prozess den geschriebenen Wert in X vorfinden.
3. Zwei Schreiboperationen von zwei Prozessen in die
Speicherstelle X sollte von jedem Prozess in der gleichen Reihenfolge gesehen werden. (Schreiben ist serialisiert)
Wie erreicht man Kohärenz?
Write‐Invalidate‐Protokoll: Wenn ein Prozess in einen Speicherstelle schreibt wird die Speicherstelle in den Caches aller anderen Prozesse invalidiert.
Wie wird das Invalidieren technisch erreicht? Snooping: Jeder Cache‐Controller überwacht den gemeinsamen Bus, ob auf einen eigenen gecachten Inhalt
geschrieben wird.
Prozessor‐
aktivität
Busaktivität Inhalt des Caches von CPU A
Inhalt des Caches von CPU B
Speicher‐
inhalt für X 0
CPU A liest X Cache‐Miss für X 0 0
CPU B liest X Cache‐Miss für X 0 0 0
CPU A schreibt 1 nach X
Cache‐
Invalidierung für X
1 1
CPU B liest X Cache‐Miss für X 1 1 1
Ergänzung: RAM und ROM
Speichern eines Bits versus viele MB
Wir wissen wie wir einzelne Bits speichern können (Erinnerung:
Latches, Flip‐Flops)
CK
D Q
Mehrere solcher Bausteine können zu Register zusammengebaut werden
Wie baut man daraus aber komplexe RAM‐Bausteine?
Beispiel: Speicherbaustein mit Adressierung
Dateneingänge (3 Bit): I0, I1, I2 Datenausgänge (3 Bit): O1, O2, O3 Adressleitungen (4 „Wörter“): A0, A1 Kontrollleitungen:
• CS = Chip‐Select
• RD = Read (=1) / Write (=0)
• OE = Output Enable
Lesen und Schreiben am Beispiel…
Wenn man entweder liest oder schreibt
können I0, I1, I2und O1, O2, O3auch dieselben Leitungen sein (das spart Pins und
Busleitungen). Dies erfordert aber, dass beim Schreiben die Ausgabe getrennt wird.
Baustein hierfür: noninverting und inverting Buffer:
Erweiterung von Adressraum und Bit‐Tiefe
Erweiterung des vorigen Beispiels ist offensichtlich:
• Vergrößerung des Adressraums (in der Größenordnung 2n): Füge eine
Adressleitung hinzu und verdoppele die Anzahl Zeilen
• Vergrößerung der Bit‐Tiefe (beliebig):
Füge in jede Zeile eine/mehrere Spalte/n hinzu
Zwei‐dimensionales sich wiederholendes Muster:
• lässt sich gut mit dem Konzept von integrierten Schaltung vereinen (z.B. kein Anwachsen von
Leitungsüberkreuzungen)
• Speicherkapazität ist nur direkt an Chip‐
Integrationsdichte gekoppelt
Verschiedene Chip‐Organisationsformen möglich. Beispiel für zwei 4Mbit‐Chip‐
Varianten:
Variante (a): wie eben nur größer Variante (b):
• 2048x2048 Matrix mit 1‐Bit‐Zellen
• Adressierung ist zweistufig (z.B. erst Row Address Strobe (RAS) und dann Column Address Strobe (CAS))
Organisation als Matrix
n x n‐Matrix‐Konzept des vorigen Beispiels allgemein:
• Geeignet für große Speicher‐Chips
• Reduziert die Anzahl Pins
• Adressierung dauert aber doppelt so lang
• Mögliche Optimierung:
• Teile zuerst die Row‐Adresse mit
• Anschließend können innerhalb dieser Row mit einer Sequenz von Column‐
Adressen Speichereinträge erreicht werden
Mehrere n x n ‐ 1‐Bit‐Bausteine lassen sich auch parallel zu größerer Bit‐Tiefe zusammenbringen, z.B. Tiefe 8‐Bit
Weitere Aspekte
Matrix muss nicht Quadratisch sein (z.B. 13 Rows und 10 Columns)
Zusätzlich kann Speicher noch in Bänken organisiert sein (z.B. 4 Bänke mit je 128Mbit ergibt 512 Mbit)
Zwei Beispiele eines 512Mbit‐Chips:
• Vier interne Bänke a 128MBit (d.h. zwei Bank‐Select‐Leitungen)
• Variante (a): 32M x 16 Design mit 13‐Bit‐RAS und 10‐Bit‐CAS => 213+10+2 = 225 interne 16‐Bit‐Zellen
• Variante (b): 128M x 4 Design mit 13‐Bit‐RAS und 12‐Bit‐CAS => 213+12+2 = 227 interne 4‐Bit‐Zellen
SRAM und DRAM
Zwei RAM‐Varianten: SRAM und DRAM Static RAM (SRAM)
• Aufgebaut mit Schaltungen wie die diskutierten Flip‐Flops
• Zustand bleibt erhalten solange Strom anliegt
• Sehr schneller Speicher (Zugriffszeit wenige nsec) Dynamic RAM (DRAM)
• Nutzt keine Flip‐Flops sondern Array von Zellen mit je einem Transistor und einem winzigen Kondensator pro Bit
• Ladezustand des Kondensator (aufgeladen/entladen) stellt 1‐Bit‐Information dar
• Kondensator entladen sich => damit periodischer „Refresh“ notwendig (alle paar Millisekunden)
FPM, EDO, SDRAM und DDR
DRAM‐Varianten: z.B. FPM (älter) und EDO (neuer) Fast Page Mode (FPM) DRAM
• Matrix zur Adressierung von Bit
• Eine Row‐Adresse und anschließend aufeinander folgende Column‐Adressen
• RAM läuft unabhängig (asynchron) vom Haupt‐Systemtakt Extended Data Putput (EDO) DRAM
• Nächste Speicherreferenz ist möglich bevor die vorige beendet wurde (vgl. Pipelining‐Prinzip)
• Erhöht nicht die individuelle Speicherzugriffzeit aber den Speicherdurchsatz Synchronous DRAM (SDRAM)
• Hybrid aus dynamischem und statischem DRAM durch den Haupt‐Systemtakt getriggert
• Keine Kontrollnachrichten zwischen Prozessor und RAM wie bei asynchronem RAM erforderlich
• Wesentlich schneller
Double Data Rate (DDR) SDRAM
• Output bei fallender und steigender Clock‐Flanke => verdoppelt die Datenrate
ROM
Read Only Memory (ROM) – Zum Chipherstellungsprozess wird das Bitmuster festgelegt;
besonders billiger Speicher
Programmable ROM (PROM) – kann einmalig Programmiert werden; Meist ein Feld von Column‐Row‐Adressierbaren Knotenpunkten die über einen Eingangs‐Pin einmalig auf einen Bit‐Wert gesetzt werden können
Erasable PROM (EPROM) – Belichtung des Quarz‐Fenster mit starkem UV‐Licht für 15 Minuten setzt alle Bit‐Werte zurück auf 1. Erneutes Setzen der Bits damit möglich EEPROM – Löschen mittels elektrischer Impulse; Re‐Programmierung direkt am Chip möglich (anstatt wie bei EPROM in spezieller Apparatur)
Diskussion:
EEPROMS typischerweise wesentlich kleiner als EPROMS und nur halb so schnell
Flash‐Speicher
Flash‐Speicher: nichtvolatiler Halbleiterspeicher.
Vorteile gegenüber Disks:
• Latenz ist 100 bis 1000 fach schneller
• Kleiner
• Größere Leistungseffizienz
• Größere Shock‐Resistenz Nachteile gegenüber Disks:
• Höherer Preis pro GB
• Flash‐Speicher‐Bits sind nach vielem Überschreiben nicht mehr verwendbar (Wear‐Out).
Flash‐Speicher muss ein entsprechendes Wear‐Leveling durchführen.
NOR‐ und NAND‐Flash‐Speicher
Zusammengefasst
Typ Kategorie Löschen Volatil Typische Anwendung
SRAM R/W Elektr. Ja Level1/2 Cache
DRAM R/W Elektr. Ja Hauptspeicher (alt) SDRAM R/W Elektr. Ja Hauptspeicher (neuer)
ROM Read‐
Only
Nicht möglich
Nein Produkte großer Stückzahl PROM Read‐
Only
Nicht möglich
Nein Produkte kleinerer Stückzahl EPROM Read‐
Mostly
UV‐Licht Nein Prototyping EEPROM Read‐
Mostly
Elektr. Nein Prototyping
Flash R/W Elektr. Nein Sekundärer Speicher
Zusammenfassung und Literatur
Zusammenfassung
• Cache‐Ziel: Speicher so groß wie auf unterstem Level aber annähernd so schnell wie auf höchstem Level.
• Warum funktionieren Caches überhaupt so gut?
Lokalitätsprinzip.
• Virtueller Speicher ist prinzipiell das selbe wie ein Cache. Auch hier gelten dieselben Cache‐Prinzipien (z.B. Lokalität)
• Insgesamt ergibt sich eine Hierarchie von Caches.
• Caches sind prinzipiell vor der Software unsichtbar.
Dennoch ist es sinnvoll diese in der Software zu beachten (z.B. Speicherblöcke in Schleifen Cache‐
günstig durchlaufen, Prefetching)
Literatur
[PattersonHennessy2012] David A. Patterson und John L.
Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
5.1 Introduction
5.2 The Basics of Caches
5.3 Measuring and Improving Cache Performance 5.4 Virtual Memory
5.8 Parallelism and Memory Hierarchies: Cache Coherence 6.4 Flash‐Storage
[Tanenbaum2001] Andrew S. Tanenbaum, „Modern Operating Systems“, Second Edition, 2001
4.8 Segmentation