228 lines
6.4 KiB
Markdown
228 lines
6.4 KiB
Markdown
# Caches
|
|
## Cache-Speicher
|
|

|
|
- Deutlich schneller als Zugriff auf Hauptspeicher
|
|
- viel kleiner als Hauptspeicher
|
|
|
|
## Grundprinzipien
|
|

|
|
|
|
## Speicher-Zugriff über Cache
|
|
- Transparenter Zugriff für die CPU
|
|
- Zugriff auf Speicher anhand der Speicheradresse aus der CPU
|
|
- Daten werden zurückgeliefert
|
|
- dazwischen: Cache
|
|
|
|
## Aufbau Cache Speicher
|
|

|
|
- Cache Line
|
|
- Einheit für Kopie eines Memory-Blocks
|
|
- mehrere Worte
|
|
- Index
|
|
- Adressiert die Cache-Line
|
|
- Data
|
|
- Daten aus dem Speicher
|
|
- V
|
|
- Valid Bit
|
|
- 1 = Vorhanden
|
|
- 0 = nicht Vorhanden (_Anfangswert_)
|
|
- Tag
|
|
- Blockadresse
|
|
- welcher zum Index passende Memory-Block ist abgelegt?
|
|
|
|
### Offset
|
|
#### Zugriff innerhalb des Caches
|
|
- Mit Offset innerhalb der Cacheline auf einzelne Wörter/Bytes zugreifen
|
|
- Beispiel
|
|
- Byte-Offset im Speicher
|
|
- 2Bit
|
|
- Größe Cache-Line
|
|
- 4 Byte
|
|
- Wort-Offset für Adressierung der Wörter in Cache-Line
|
|
- 2 Bit
|
|
- Offset in ADresse gesamt
|
|
- 4 Bit
|
|
|
|
#### Offset Beispiel
|
|

|
|

|
|
|
|
### Index: Cache Adressierung
|
|

|
|
- Speicherort wird durch Index-Teil der Adresse bestimmt
|
|
- $Cacheadresse = Speicheradresse \mod ZeilenImCache$
|
|
|
|
|
|
### Tag: Zuordnung der Daten
|
|
- Woher ist bekannt welcher Block im Speicher abgelegt ist
|
|
- Speichern der Blockadresse (TAG) und der Daten
|
|
- 
|
|
|
|
### Assoziativität: Cache-Zeilen mit gleichem Index
|
|

|
|
- Durch weiteren Satz von Cache-Lines
|
|
- Daten mit gleichem Index aber unterschiedlichen Tags speichern
|
|
- 
|
|
|
|
#### Grad der Assoziativität
|
|
- höhere Assoziativität verringert Fehlerzugriffrate
|
|
- 1-Fach: 10,3%
|
|
- 2-Fach: 8,6%
|
|
- 4-Fach: 8,3%
|
|
- 8-Fach: 8,1%
|
|
|
|
|
|
## Cache-Beispiel
|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|
|
|
|
|
## Zusammenfassung Adressierung
|
|

|
|
|
|
## Cache Organisation (Assoziativität)
|
|
- [Direkt abgebildet (direct mapped)](#direkt-abbildender-cache)
|
|
- ein Datenwort kann in einem Eintrag abgelegt sein
|
|
- 
|
|
- [Voll assoziativ (fully associative)](#voll-assoziativer-cache)
|
|
- ein Datenwort kann in einem beliebigen Cache-Eintrag abgelegt sein
|
|
- 
|
|
- [Satz assoziativ (set associative)](#n-fach-satzassoziativer-cache)
|
|
- ein Datenwort kann in wenigen Cache-Einträgen (_typischerweise 2-8_) abgelegt sein
|
|
- 
|
|
|
|
### Direkt abbildender Cache
|
|

|
|
|
|
### Voll assoziativer Cache
|
|

|
|
|
|
### N-Fach satzassoziativer Cache
|
|

|
|
|
|
## Lesezugriff
|
|
- Wenn Prozessor Wort aus Hauptspeicher lesen will
|
|
- Cache-Logik prüft, ob Wort schon im Cache ist
|
|
- **cache hit**
|
|
- Daten im Cache
|
|
- Wort an Prozessor weitergeben
|
|
- Trefferrate = Treffer / Zugriffsrate
|
|
- **cache miss**
|
|
- Daten nicht im Cache
|
|
- Daten aus HS lesen
|
|
- Fehlerzugriffsrate = 1 - Trefferrate
|
|
- 
|
|
|
|
|
|
## Lesen von Daten
|
|
### Ersetzungsstrategien im assoziativen Cache
|
|
- Falls Wort nicht im Cache vorhanden
|
|
- aus Speicher in Cache laden
|
|
- Bei direkt abgebildeten Cache
|
|
- Zuordnung der Adresse des Wortes zu einer Cache-Zeile eindeutig
|
|
- Beim assoziativen Cache verschiedene Strategien möglich
|
|
- **Least Recently Used (LRU)**
|
|
- Wählt Zeile, die am längsten nicht genutzt wurde
|
|
- Für mehr als 4-Fach zu aufwendig
|
|
- **Zufällig**
|
|
- Wähle zufällige Zeile
|
|
- Ähnliche Trefferrate wie LRU bei hoher Assoziativität
|
|
- **Round-Robin**
|
|
- Zyklischer Zugriff
|
|
|
|
### Initiales Lesen von Daten
|
|
- Zwei Lese- / Füllstrategien
|
|
- **on demand, demand fetching**
|
|
- Beim ersten Lesen einer Information aus HS
|
|
- ganze Zeile in Cache laden, falls noch nicht drin
|
|
- **Prädiktiv, prefetch**
|
|
- Vorhersage, welche Speicherzeilen gebraucht werden
|
|
- Während Leerlaufphasen in Cache vorladen
|
|
- Zweiter Programmzähler (Remote PC)
|
|
- Künftigen Programmablauf bestimmen
|
|
- Gut weil
|
|
- Bessere Nutzung [räumlicher Lokalität](Rechnersysteme_Intro.md#r-umliche-lokalit-t)
|
|
- Prefetching durch Hardware
|
|
- Stream Buffers zwischen Cache und Speicher
|
|
- Prefetching durch Software
|
|
- ```c++
|
|
for (int i = 0; i < 1024; i++){
|
|
prefetch (array1 [i+k]); // stride k
|
|
array1[i] = 2* array1[i];
|
|
}
|
|
```
|
|
|
|
|
|
## Schreibzugriff
|
|
- Daten in Cache und HS müssen konsistent bleiben
|
|
- Wenn Prozess Speicherstelle schreiben möchte, die schon im Cache ist
|
|
- **write-through**
|
|
- Schreiben erfolgt sowohl im Cache als auch im HS
|
|
- langsame Schreibzugriffe
|
|
- **write-back**
|
|
- Schreiben nur im Cache
|
|
- Eintrag markieren
|
|
- _dirty bit_
|
|
- Wenn Cache-Line verdrängt wird in HS schreiben
|
|
- _Gefahr Inkonsistenz_
|
|
- **No-write**
|
|
- Wort nur im HS schreiben
|
|
- im Cache als invalid markieren
|
|
- langsame Schreibzugriffe
|
|
- ggf. danach langsame Lesezugriffe
|
|
|
|
### Initiales Schreiben von Daten
|
|
- **write-around**
|
|
- nur in HS schreiben
|
|
- **write-allocate**
|
|
- fetch on write
|
|
- erst Cache-Line in den Cache, dann wie oben
|
|
|
|
### Übliche Kombinationen
|
|
- write-allocate → write-back
|
|
- write around → write through
|
|
|
|
### Schreib-Buffer
|
|
- 
|
|
- beschleunigt Schreiben, da kein Stall erfolgt
|
|
- Wenn Buffer voll ist
|
|
- strukturelle Abhängigkeit
|
|
- Warten bis Schreiben in HS abgearbeitet ist
|
|
- Bei direkt folgendem Lesezugriff auf zu schreibende Daten
|
|
- Datenabhängigkeit
|
|
|
|
|
|
## Cache Spezifikation
|
|
- Definiert durch
|
|
- Anzahl der Cache-Zeilen C
|
|
- Größe einer Cache-Zeile L
|
|
- Assoziativität m
|
|
- Daraus lässt sich bestimmen
|
|
- Aufteilung der ADress in Offset, Index, Tag
|
|
- [Gesamtgröße Cache](#gesamtgr-e-cache)
|
|
|
|
## Gesamtgröße Cache
|
|

|
|
|
|
## Cache-Leistung
|
|

|
|
|
|
### Beispiel Cache Leistung
|
|

|
|

|
|
|
|
## Multilevel Cache Organisation
|
|

|
|
- Level 1
|
|
- Cache für Instruktionen und Daten
|
|
- Level 2
|
|
- vereint für Instruktionen und Daten
|
|
- Level 3
|
|
- auf Board-Ebene (Static RAM)
|
|
|