# Caches
## Cache-Speicher
![image_502.png](image_502.png)
- Deutlich schneller als Zugriff auf Hauptspeicher
- viel kleiner als Hauptspeicher

## Grundprinzipien
![image_503.png](image_503.png)

## 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
![image_504.png](image_504.png)
- 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
![image_506.png](image_506.png)
![image_505.png](image_505.png)

### Index: Cache Adressierung
![image_507.png](image_507.png)
- 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
- ![image_508.png](image_508.png)

### Assoziativität: Cache-Zeilen mit gleichem Index
![image_510.png](image_510.png)
- Durch weiteren Satz von Cache-Lines
  - Daten mit gleichem Index aber unterschiedlichen Tags speichern
- ![image_509.png](image_509.png)

#### 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
![image_511.png](image_511.png)
![image_512.png](image_512.png)
![image_513.png](image_513.png)
![image_514.png](image_514.png)
![image_515.png](image_515.png)
![image_516.png](image_516.png)
![image_517.png](image_517.png)


## Zusammenfassung Adressierung
![image_518.png](image_518.png)

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

### Direkt abbildender Cache
![image_519.png](image_519.png)

### Voll assoziativer Cache
![image_520.png](image_520.png)

### N-Fach satzassoziativer Cache
![image_521.png](image_521.png)

## 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
- ![image_525.png](image_525.png)


## 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
- ![image_526.png](image_526.png)
- 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
![image_527.png](image_527.png)

## Cache-Leistung
![image_528.png](image_528.png)

### Beispiel Cache Leistung
![image_529.png](image_529.png)
![image_530.png](image_530.png)

## Multilevel Cache Organisation
![image_531.png](image_531.png)
- Level 1
  - Cache für Instruktionen und Daten
- Level 2
  - vereint für Instruktionen und Daten
- Level 3
  - auf Board-Ebene (Static RAM)

