# 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)