Hardware-Zone Schriftzug

Neueste Artikel

Cache

 

Bei den ersten CPUs wurden Befehle und Daten noch direkt aus dem Arbeitsspeicher in die Register geladen. Die CPU musste deshalb nach jedem Absenden der Anfrage warten, bis die Adresse über die Adressleitungen zum Speicher übertragen, die Adresse dort dekodiert (sofern der DRAM wieder bereit war) und die angeforderten Daten über die Datenleitungen eintrafen. Je schneller die CPU wurde, desto negativer wirkten sich die hohen Zugriffszeiten auf die Leistung aus. Deshalb wurde mit dem 80486-Mikroprozessor ein kleiner Pufferspeicher eingeführt, der als Cache bezeichnet wiurde. Dieser war im Vergleich zum Hauptspeicher zwar sehr schnell, aber winzig. Obwohl nur ein Bruchteil der Befehle und Daten der laufenden Programme in einen Cache passen, können über 90% aller Anfragen der CPU durch den Cache bedient werden. Was zunächst paradox klingen mag, ist durch die Eigenschaften eines Speicherzugriffs begründet:

  • Zeitliche Lokalität: Auf Daten oder Befehle, die bereits einmal aus dem Speicher geholt wurden, wird meistens erneut zugegriffen.
  • Räumliche Lokalität: Da Programmdaten meistens direkt nebeneinander im Speicher abgelegt werden, ist es wahrscheinlicher, dass in der Folge auch benachbarte Daten angefordert werden.

Programme greifen also statistisch gesehen nur auf einen kleinen Bereich des Arbeitsspeichers zu!

Wenn die Daten im Cache gefunden wurden, spricht man von einem „Cache-Hit“. Wenn die Daten nicht im Cache sind, also ein „Cache-Miss“ vorliegt, müssen sie aus dem Arbeitsspeicher geholt werden.

Cachehierarchie

Wenn man mehrere Caches einsetzt, kann man die Wahrscheinlichkeit eines „Cache-Hit“ noch steigern und damit die Anzahl der Zugriffe auf den Arbeitsspeicher weiter senken. Das ist effektiver und günstiger als ein einzelner, großer Cache. In modernen CPUs wird ein mehrstufiges Cache-Konzept mit klarer Hierarchie eingesetzt. Meistens gibt es drei Hierarchieebenen (engl. Level): 1L-Cache, 2L-Cache und 3L-Cache. Da auf der ersten Ebene häufig parallel auf Befehle und Daten zugegriffen wird, ist der Cache auf dieser Ebene (1st-Level-Cache) oft in einen separaten Befehls- und Datencache unterteilt. Während der schnelle 1st-Level-Cache nur vergleichsweise wenig Daten und Befehle aufnehmen kann, passen in einen langsameren 3rd-Level-Cache auch mehrere Megabyte Daten. Wie die Daten aus dem Arbeitsspeicher auf die einzelnen Caches verteilt werden, wird durch die Cache-Strategie festgelegt:

Exklusive Cache-Strategie

Bei der von AMD-Prozessoren genutzten Strategie wird ein an einer bestimmten Adresse gespeicherter Datenblock nur in einem Cache abgelegt. Wenn die Daten im L1-Cache nicht gefunden wurden, wird der jeweils nächsthöhere Cache abgefragt usw. Wenn in einen bereits gefüllten Cache neue Daten geschrieben werden, wird der zu ersetzende Datenblock jeweils in den Cache der nächsthöheren Ebene verschoben. Die Größe des gepufferten Speicherbereichs ergibt sich aus der Summe der Kapazitäten von L1-, L2- und L3-Cache.

  • Der verfügbare Speicherplatz wird effizienter genutzt, aber dafür sind die Zugriffszeiten höher.

Inklusive Cache-Strategie

Bei Intel-CPUs wird ein an einer bestimmten Adresse gespeicherter Datenblock in jedem Cache abgelegt.

Vorteil:

  • kürzere Zugriffszeiten, da beim Ersetzen vorhandener Daten keine Übertragung in einen anderen Cache stattfindet und beim Lesezugriff immer auf den schnellsten Cache zugegriffen wird.

Nachteil:

 

  • Es sind größere Caches für dieselbe Menge an Daten nötig als bei einer exklusiven Strategie.

Aufbau

Ein Cache besteht im Wesentlichen aus folgenden Komponenten:

Cache-Controller

Der Cache-Controller steuert und überwacht den Datenaustausch zwischen CPU und Cache. Er überträgt die von der CPU angeforderten Daten vom Cache in den Arbeitsspeicher (und umgekehrt) und sorgt dafür, dass der Cache-Inhalt stets auf dem aktuellen Stand ist.

Mehreren Cache-Zeilen (engl. Cache-Lines)

Da die Zugriffszeit des Arbeitsspeichers relativ lang ist, werden bei jedem Zugriff mehrere Datenworte hintereinander übertragen. Ein solcher Block besteht üblicherweise aus 8 je 64 Bit breiten Datenworten. Im Cache wird jeder Datenblock in einer eigenen Cache-Zeile (engl. „Cache-Lines“) abgelegt. Mehrere Cache-Zeilen bilden einen Satz (engl. „Set“).

Zu jeder Cache-Zeile wird ein sogenanntes Valid-Bit („Gültigkeits“-Bit) gespeichert, das angibt, ob der zugehörige Datenblock überhaupt noch im Arbeitsspeicher vorhanden ist oder nicht. Beim Hochfahren des PCs sind zunächst alle Valid-Bits auf 0 („ungültig“) gesetzt.

Die Anzahl der Cache-Zeilen richtet sich nach der Größe des Cache und der Blockgröße. Beispiel: Ein Cache mit einer Kapazität von 64 KiB und einer Blockgröße von 64 Byte (8 x 8 Byte) hat 1.024 Cache-Zeilen (65.536 / 64).

Tag-Register

Jede Cache-Line ist mit einem eigenen Tag-Register verbunden, in dem die Adresse des entsprechenden Datenblocks im Arbeitsspeicher (Tag) abgelegt wird.

Funktionsweise

Nach außen hin verhält sich ein Cache wie normaler Arbeitsspeicher: Bei einem Lesezugriff sendet die CPU die Speicheradresse an den Cache und erhält kurze Zeit später die an der entsprechenden Speicherstelle abgelegten Daten zurück, bei einem Schreibzugriff wird über die Speicheradresse zuerst die Speicherstelle ausgewählt und dann die Daten dort abgelegt. Wie die Speicheradresse vom Cache interpretiert wird, hängt von der internen Organisation des Cache ab. Näheres dazu auch unter Adressformate.
cache
Abb.: Vereinfachte Darstellung eines Lesezugriffs bei einem 16 Byte (8 Zeilen x 2 Byte) großen direkt-abbildenden Cache

Beim Zugriff auf einen Cache muss zuerst überprüft werden, ob für die angegebene Adresse bereits eine Zeile im Cache existiert. Dabei werden die höherwertigen Bits der Adresse (gelb) mit dem Inhalt der Tag-Register verglichen. Das erfolgt mit Hilfe spezieller elektronischer Schaltkreise, Komparatoren genannt.

Im Falle einer Übereinstimmung hängt die weitere Vorgehensweise davon ab, ob Daten gelesen oder geschrieben werden sollen.

  • Lesezugriff: Zuerst wird überprüft, ob die Cache-Zeile gültig ist, d.h. ob an der Adresse überhaupt (noch) ein Datenblock im Arbeitsspeicher existiert. Nur wenn das Valid-Bit gültig ist (1), wird die Cache-Zeile ausgelesen und die über das Offset adressierten Bytes an die CPU übertragen.
  • Schreibzugriff: Die Daten werden in die ausgewählte Cache-Zeile geschrieben. Dabei werden die bereits vorhandenen Daten überschrieben.

Wenn keine Übereinstimmung gefunden wird, spielt die Ersetzungsstrategie eine entscheidende Rolle:

 

  • Beim Lesezugriff wird der adressierte Datenblock als Erstes aus dem Arbeitsspeicher oder dem Cache der höheren Ebene in die Cache-Zeile, die durch die Ersetzungsstrategie bestimmt wurde, übertragen. Das Valid-Bit wird auf 1 (gültig) gesetzt, bevor die Ausgabe an die CPU erfolgt.
  • Schreibzugriff: Es gibt zwei Möglichkeiten: Wenn der Cache nicht voll ist, wird die erste freie (ungültige) Cache-Zeile (Valid-Bit = 0) ausgewählt. Anderenfalls bestimmt die gewählte Ersetzungsstrategie eine bereits beschriebene Cache-Zeile. Anschließend werden die Daten von der CPU in die ausgewählte Cache-Zeile geschrieben. Das Valid-Bit wird auf 1 gesetzt, sobald die Cache-Zeile befüllt ist.

Adressformate

Vollassoziativer Cache

adresse1
Bei vollassoziativen Caches besteht die Speicheradresse aus zwei Teilen: Einem Adress-Tag, der den entsprechenden Speicherblock im Arbeitsspeicher angibt, und einem Offset (Adressversatz), der ein Byte innerhalb dieses Blocks adressiert. Bei einer Adresslänge von 32 Bit und einer Blockgröße von 16 Byte benötigt man z.B. 4 Bit für den Offset (2^4 = 16 oder Logarithmus zur Basis 2 von 16), die restlichen 28 (höherwertigen) Bits werden für die Blockadresse verwendet.

Direkt-abbildender und n-fach satzassoziativer Cache

Bei direkt-abbildenden und n-fach satzassoziativen Caches besteht die Adresse noch zusätzlich aus einem Index, der die Position der Zeile bzw. des Satzes im Cache angibt. Ein direkt-abbildender Cache mit 512 Zeilen benötigt z.B. einen 9 Bit langen Index (2^9 = 512, log2(512) = 9).
adresse2 2wncbgr1
Um zu ermitteln, auf welche Cache-Zeile oder welchen Satz die Adresse verweist, wird folgende Funktion verwendet: i modulo k^2 („k hoch 2“), wobei i die höherwertigen Bits der Speicheradresse (ohne Offset) und k^2 die Anzahl der Cache-Zeilen bzw. Sätze ist.
Ein einfaches Beispiel: Ein 64 Byte großer Cache hat 4 Cache-Zeilen. Auf welche Cache-Zeile verweist Adresse 18 (= 10010)?
Auf Zeile 2 (18 modulo 4 = 2 = 0010 binär).

Alternativ kann auch über folgende Methode die Cache-Zeile ermittelt werden: Dazu muss zuerst die Blockgröße in Byte berechnet werden. Sie beträgt im Beispiel 16 Byte (64 Byte / 4 Zeilen = 16). Um diese 4 Zeilen ansprechen zu können, wird eine 2 Bit lange Blockadresse benötigt (2^2 = 4). Um die Cache-Zeile zu erhalten, müssen die Tag-Bits von den höherwertigen Bits der Adresse (ohne Offset) abgezogen werden: 10010 – 10000 = 00010 = 2 dezimal.

Merkmale eines Cache

Neben Zugriffszeit, Kapazität und Datendurchsatz gibt es bei Caches noch weitere wichtige Unterscheidungsmerkmale:

Die Trefferquote (Anzahl Cache-Hits / Anzahl Zugriffe) ist das wichtigste Merkmal eines Cache, da sie maßgeblich für die Verarbeitungsgeschwindigkeit der CPU ist.
Beispiel: Eine CPU mit einer Taktfrequenz von 1 GHz benötigt genau einen Takt für die Ausführung eines einfachen Befehls, das entspricht 1 ns (1 / Taktfrequenz). Bei einem Zugriff auf den Arbeitsspeicher beträgt die Ausführungszeit 11 ns (10 ns Zugriffszeit), bei einem erfolgreichen Cache-Zugriff aber nur 2 ns (1 ns Zugriffszeit). Geht man von einer Cache-Trefferquote von 80% aus, erreicht die CPU eine Geschwindigkeit von 419 Mio. Befehlen/s ( [(1.000 MHz x 0,8) / 2] + [(1.000 MHz x 0,2) / 11] ), bei einer Trefferquote von 95% sind es 525 Mio. Befehle/s ( [(1.000 MHz x 0,95) / 2] + [(1.000 MHz x 0,05) / 11] ). Allein durch eine höhere Trefferquote könnte die CPU-Leistung bereits um 25% gesteigert werden!

Die Trefferquote ist abhängig von:

  • der internen Organisation des Cache: Vollassoziativ, direkt-abbildend („Direct-Mapped“) oder n-fach satzassoziativ
  • der Verdrängungs- oder Ersetzungsstrategie: Da nicht alle Daten in den Cache passen, muss durch eine Ersetzungsstrategie bestimmt werden, welche Cache-Zeilen zuerst ersetzt werden (zufällig, LRU oder Pseudo-LRU).
  • der Schreibstrategie: Sie legt fest, wann die im Cache geänderten Cache-Zeilen in den nächsthöheren Cache bzw. in den Arbeitsspeicher geschrieben werden (write-through oder write-back).

Organisation

 

Die interne Organsation des Cache wird hauptsächlich durch die Assoziativität bestimmt. Sie legt fest, auf wie viele Cache-Zeilen eine Adresse im Speicher abgebildet werden kann.

Hinweis: In den folgenden Beispielen wird von einer Adressbreite von 32 Bit und einer Blöckgröße von 16 Byte ausgegangen. Ein Cache mit einer Größe von 8 KiB (8.192 Bytes) besteht folglich aus 512 Cache-Zeilen (8.192 / 16 = 512).

vollassoziativ k4foo4ed

Vollassoziativ (Assoziativität = m)

Es gibt nur einen „Satz“, der alle 512 Cache-Zeilen enthält. Die angefragte Adresse kann auf eine beliebige der 512 Cache-Zeilen zeigen, d.h. es werden 512 Komparatoren benötigt. Eine vollassoziative Organisation lohnt sich deshalb nur bei kleinen Caches. Dafür liefern vollassoziative Caches in Verbindung mit einer effektiven Ersetzungsstrategie die höchste Trefferquote.

Direkt-abgebildet (Assoziativität = 1)

Jede Cache-Zeile entspricht genau einem Satz. Die Blockadresse wird „direkt“ auf eine bestimmte Cache-Zeile abgebildet. Dazu wird ein Teil der Adresse als Index verwendet (im Beispiel 9 Bit, 2^9 = 512), der die Cache-Zeile angibt. Im Vergleich zum vollassoziativen Cache ist der Hardwareaufwand gering: Die Tag-Register sind kleiner (19 statt 28 Bit) und es wird nur 1 Komparator (statt 512) benötigt. Bei der direkten Abbildung kann es allerdings zu Zugriffskonflikten kommen: Wenn ein Programm direkt nacheinander auf Speicheradressen zugreift, die derselben Zeile im Cache zugeordnet sind, überschreiben diese sich gegenseitig. Ein direkt-abbildender Cache muss deshalb sehr groß sein, um genügend Zeilen ansprechen zu können. Alternativ kann auch zusätzlich ein Victim-Cache eingesetzt werden.

nichtassoziativ rsod2dgf
nfachassoziativ 91ni7t1j

n-fach-satzassoziativ (Assoziativität = n)

Der Cache wird in mehrere Sätze (Anzahl Cache-Zeilen / n) unterteilt, die jeweils n Cache-Zeilen enthalten. Wenn ein Satz n Zeilen hat, spricht man von einem n-fach-satzassoziativen Cache. Ein 4-fach-satzassoziativer Cache mit 512 Zeilen hat z.B. 128 Sätze á 4 Zeilen. Die angefragte Adresse kann auf jede Cache-Zeile eines Satzes abgebildet werden. Im Vergleich zum vollassoziativen Cache sind die Tag-Register kleiner und es werden nur n Komparatoren benötigt. Diese Organisationsform ermöglicht hohe Trefferquoten bei vertretbarem Hardware-Aufwand.

Ersetzungsstrategien

 

Caches sind um ein Vielfaches kleiner als Arbeitsspeicher und wären deshalb sehr schnell überfüllt. Um dies zu vermeiden, müssen Daten im Cache regelmäßig ersetzt werden. Welche Daten zuerst überschrieben werden sollen, entscheidet die Ersetzungsstrategie. Die am häufigsten anzutreffenden Strategien sind:

LRU (Least Recently Used)

Es wird zuerst die Cache-Zeile ausgewählt, auf die zuletzt am wenigsten zugegriffen wurde. Jede Zeile wird dazu mit einem Zähler versehen, der bei jedem Zugriff für jede Zeile um eins erhöht und damit sozusagen das „Alter“ des Eintrags darstellt. Die Zeile mit dem höchsten Alter wird ersetzt. Je mehr Cache-Einträge vorhanden sind, desto mehr Bit müssen für den Zähler reserviert werden. Für große Caches ist dieses Verfahren deshalb ungeeignet.

Pseudo-LRU

Intel führte deshalb ein Pseudo-LRU-Verfahren ein, bei dem ein binärer Entscheidungsbaum zur Auswahl der Cache-Zeile genutzt wird, auf die zuletzt am wenigsten zugegriffen wurde. In jeder Zeile werden drei Bits gespeichert, die jeweils für einen Knoten stehen:

  • Das linke Bit wird bei einem „Cache-Hit“ in Zeile A oder B auf 1 gesetzt und bei einem „Cache-Miss“ bzw. „Cache-Hit“ in C oder D auf 0.
  • Das mittlere Bit wird bei einem „Cache-Hit“ in Zeile A auf 1 gesetzt und bei einem „Cache-Miss“ bzw. „Cache-Hit“ in B auf 0.
  • Das rechte Bit wird bei einem „Cache-Hit“ in Zeile C auf 1 gesetzt und bei einem „Cache-Miss“ bzw. „Cache-Hit“ in D auf 0.

Bei einem Zugriff wird immer die Cache-Zeile im Satz ausgewählt, auf die das Bit-Muster verweist (siehe Abbildung):
00x = A, 01x = B, 1×0 = C, 1×1 = D
(Quelle)

Unabhängig von der Größe des Cache werden nur 3 Bit pro Cache-Zeile benötigt. Außerdem arbeitet der Algorithmus wesentlich schneller als das reine LRU-Verfahren.

pseudo

Zufallsgenerator

Die einfachste und platzsparendste Methode ist der Einsatz eines Algorithmus, der die Cache-Zeile zufällig auswählt. Es wird kein Speicherplatz für zusätzliche Bits benötigt.

Schreibstrategien

 

Die Schreibstrategie legt fest, zu welchem Zeitpunkt die geänderte Cache-Zeile in den Speicher der darüber liegenden Ebene geschrieben worden soll.

Write-Back-Strategie (write-back = zurückschreiben)

Der geänderte Datenblock wird zunächst nur in die Cache-Zeile geschrieben. Erst wenn diese ersetzt wird, schreibt der Cache-Controller die Daten zurück in den Cache der höheren Ebene bzw. in den Arbeitsspeicher. Um feststellen zu können, ob einzelne Bytes seit dem letzten Zugriff auf die Zeile verändert wurden, ist neben dem Valid-Bit ein zusätzliches Status-Bit notwendig: Das Dirty- oder Modified-Bit (modified = verändert). Nachteil: Bis zum Ersetzungszeitpunkt ist die Kopie des Datenblocks nicht mehr mit dem „Original“ in der höheren Ebene identisch. Das ist vor allem bei Mehrkern-CPUs mit einem gemeinsamen Cache der höheren Ebene problematisch, da die anderen CPUs nichts von der Inkonsistenz wissen und auf veraltete Daten zugreifen könnten. Abhilfe schaffen sogenannte Cache-Kohärenz-Protokolle.

Write-Through-Strategie (write-through = durchschreiben)

Der geänderte Datenblock wird gleichzeitig in die Cache-Zeile und in den Cache der höheren Ebene bzw. den Arbeitsspeicher übertragen. Nachteil: Damit die CPU nicht jedes Mal warten muss, bis die Daten in den langsameren Speicher übertragen wurden, ist der Einsatz eines zusätzlichen Zwischenspeichers erforderlich.

Cache-Kohärenz

Damit ein Prozessor nicht irgendwann mit veralteten Daten arbeitet und dann falsche Ergebnisse ausgibt, müssen zwei Voraussetzungen erfüllt sein:

  • Die Kopien der Datenblöcke im Cache müssen stets mit den entsprechenden Originalen im Arbeitsspeicher identisch sein.
  • Der Cache von CPU A muss immer auf dem gleichen Stand sein wie der Cache von CPU B (z.B. L1 von CPU A = L1 von CPU B).

Diesen Sachverhalt bezeichnet man als Cache-Kohärenz (von lat. cohaerentia = Zusammenhang).

Um eine veränderte oder ungültige Cache-Zeile zu erkennen, gibt es bereits das Modified- bzw. Valid-Bit. Wenn jeder CPU-Kern direkt auf die Caches der anderen Kerne zugreifen und dort die entsprechenden Zeilen überprüfen und beschreiben könnte, wäre es möglich, die Caches auf dem gleichen Stand zu halten. Da dieses Verfahren aber sehr aufwändig wäre und ein sehr hohes Datenaufkommen verursachen würde, setzt man Cache-Kohärenz-Protokolle ein. Ein häufig eingesetztes Protokoll ist MESI. Die Abkürzung steht für die vier Zustände, die eine Cache-Zeile annehmen kann.

mesi nhqmsd27
  • (M)odified – Geändert: Die Cache-Zeile wurde nur in diesem Cache geändert, befindet sich aber auch noch in einem anderen Cache und ist nicht mehr mit den Daten im Arbeitsspeicher identisch. Die Zeile muss deshalb erst in den Speicher zurückgeschrieben und dann der Zustand auf „Shared“ geändert werden.
  • (E)xclusive: Die Cache-Zeile befindet sich nur in diesem Cache und ist mit den Daten im Arbeitsspeicher identisch. Mögliche Zielzustände: Shared oder Modified.
  • (S)hared – Geteilt: Die Cache-Zeile befindet sich in mehreren Caches und ist mit den Daten im Arbeitsspeicher identisch – der Idealzustand. Möglicher Zielzustand: Invalid.
  • (I)nvalid – Ungültig: Die Daten sind nicht mehr verfügbar oder veraltet.

Eine Zuständsänderung wird entweder durch die Aktivitäten der CPU-Kerne oder explizit über Steuersignale ausgelöst. Dabei hören Cache-Controller ständig den zentralen Verteiler ab, über den die Geräte miteinander kommunizieren. Dieses Verfahren nennt sich „Snooping“ (von engl. to snoop = schnüffeln).

Beispiel mit zwei CPU-Kernen

mesi01

Die Ausgangssituation: Jeder Cache enthält die Cache-Zeile 5 (Status: geteilt) mit dem Wert ’10‘.

mesi02

CPU A hat eine Berechnung durchgeführt und möchte den geänderten Wert ’25‘ in den Eintrag 5 in Cache A zurückschreiben.

  • Der Cache bemerkt die Schreibanforderung und sendet ein Invalidate-Signal.
  • Der Cache von CPU B markiert Zeile 5 als ungültig, Cache A ändert den Wert in Zeile 5 auf ’25‘ und setzt ihn dann auf „Geändert“.
mesi03

CPU B möchte wenig später ebenfalls auf Zeile 5 im Cache zugreifen.

  • Cache B erkennt, dass Zeile 5 als „Ungültig“ markiert ist und möchte die entsprechenden Daten aus dem Arbeitsspeicher holen.
  • Cache A realisiert dies und findet bei sich die entsprechende Zeile, die aber als „Geändert“ gekennzeichnet ist. Die Daten im Arbeitsspeicher müssen deshalb erst aktualisiert werden. Deshalb sendet er ein Retry-Signal an CPU B, woraufhin diese den Ladevorgang sofort abbricht und einen Augenblick wartet.
mesi04

In der Zwischenzeit wird der Wert ’25‘ von Cache A in den Arbeitsspeicher übertragen und Zeile 5 anschließend auf „Geteilt“ gesetzt.

mesi05

CPU B möchte nun erneut auf Zeile 5 zuzugreifen.

  • Cache A bemerkt dies und zeigt Cache B mit einem Shared-Signal an, dass die Daten im Arbeitsspeicher nun aktuell sind.
  • Cache B lädt die Daten aus dem Speicher und markiert Zeile 5 ebenfalls mit „Geteilt“.

Besondere Caches

Es gibt eine Reihe spezialisierter Caches, die nur eine bestimmte Art von Daten aufnehmen.

Micro-Operation-Cache

Um zu vermeiden, dass ein Befehl nach jeder Fetch-Phase erneut dekodiert werden muss, werden bereits dekodierte Mikroinstruktionen in einem eigenen Cache abgelegt.

TLB (Translation Lookaside Buffer)

Ein Programm arbeitet anders als der Prozessor nicht mit physischen Speicheradressen, sondern mit logischen Adressen. [Mehr dazu unter Speicherverwaltung] Damit diese in einem zeitaufwändigen Prozess nicht jedes Mal erst umgewandelt werden müssen, wird zu jeder logischen Adresse die zugehörige physische Adresse in diesem speziellen Cache abgelegt.

BTB (Branch Target Buffer = Sprungziel-Puffer)

Der BTB enthält zu jedem Sprungbefehl die Adresse des Sprungziels. [Mehr dazu unter Sprungvorhersage] Er ist ebenfalls wie ein Cache aufgebaut, als Adress-Tag werden die niedrigstwertigen n Bit der Adresse des Sprungbefehls verwendet (n hängt von der Anzahl der Einträge ab).

Victim-Cache

Der Victim-Cache (engl. für Opfer) enthält nur Datenblöcke, die aus einem anderen Cache verdrängt, also gewissermaßen zugunsten eines anderen, aktuelleren Datenblocks „geopfert“ wurden. Es handelt sich hierbei um einen vollassoziativen Cache, der vor allem das gegenseitige Überschreiben bei Caches mit geringer Assoziativität verhindern soll (siehe direkt-abbildender Cache).