Speicherhierarchie und Caches

Lerne, warum ein Rechner kleine, schnelle Speicher mit großen, langsamen kombiniert und wie Caches die Daten, die ein Programm benötigt, in der Nähe des Prozessors halten. Vergleiche SRAM, DRAM und Flash-Speicher, finde Blöcke in direkt abgebildeten und satzassoziativen Caches, klassifiziere Fehlzugriffe und vergleiche Schreibstrategien. Berechne Trefferraten, mittlere Speicherzugriffszeiten und die Kosten von Speicherwartezyklen, erfahre, wie virtueller Speicher und der TLB Adressen übersetzen, und schreibe Schleifen und Datenstrukturen, die den Cache gut nutzen.

MittelEinheit 5 von 6 in Kurs: Rechnerarchitektur – Prozessoren, Speicher und RISC-V

Was du lernst

  1. Beschreibe, wie Programme Daten und Code wiederverwenden, vergleiche die Speichertechnologien, die sie speichern, und erkläre das Zusammenspiel schneller kleiner und langsamer großer Ebenen.
    • Erkenne zeitliche und räumliche Lokalität in Programmen
      Erkenne die beiden Arten der Lokalität bei Code- und Datenzugriffen und erkläre, warum ein kleiner, schneller Speicher dadurch die meisten Zugriffe bedienen kann.
    • Vergleiche SRAM, DRAM und Flash-Speicher
      Beschreibe, wie SRAM, DRAM und Flash Bits speichern, und vergleiche Geschwindigkeit, Speicherdichte, Kosten pro Bit, Flüchtigkeit und typische Position in der Hierarchie.
    • Beschreibe, wie die Ebenen der Speicherhierarchie zusammenarbeiten
      Benenne die Ebenen von Registern bis zum Massenspeicher, verwende die Begriffe Treffer und Fehlzugriff und erkläre, wie die Hierarchie den Eindruck eines großen, schnellen Speichers vermittelt.
  2. Verwende die Felder Tag, Index und Offset einer Adresse, um einen Block zu finden, verfolge Zugriffsfolgen und vergleiche Cacheorganisationen von direkt abgebildet bis vollassoziativ.
    • Zerlege eine Adresse in Tag, Index und Offset
      Berechne die Feldgrößen eines direkt abgebildeten Caches aus seiner Kapazität und Blockgröße, zerlege eine Adresse in ihre Felder und berechne den Speicherbedarf des Caches.
    • Verfolge Zugriffe auf einen direkt abgebildeten Cache
      Verfolge eine Folge von Adressen durch einen kleinen direkt abgebildeten Cache, halte jeden Treffer oder Fehlzugriff und den Cacheinhalt fest und erkenne Blöcke, die sich gegenseitig verdrängen.
    • Verwende satzassoziative und vollassoziative Caches
      Finde Blöcke in n-fach satzassoziativen und vollassoziativen Caches, wähle mit einer Ersetzungsstrategie einen zu verdrängenden Block und wäge niedrigere Fehlzugriffsraten gegen Hardwareaufwand und Trefferzeit ab.
  3. Beschreibe, was bei einem Fehlzugriff geschieht, klassifiziere Fehlzugriffe nach ihrer Ursache, setze Cachegröße, Blockgröße und Assoziativität zur Fehlzugriffsrate in Beziehung und vergleiche, wie Caches Schreibzugriffe behandeln.
    • Behandle Cache-Fehlzugriffe und ordne ihre Ursachen ein
      Beschreibe die Schritte eines Cache-Fehlzugriffs, ordne Fehlzugriffe als obligatorisch, kapazitätsbedingt oder konfliktbedingt ein und erkläre, wie Cachegröße, Blockgröße und Assoziativität die einzelnen Arten verändern.
    • Vergleiche Schreibstrategien für Caches
      Erkläre, wie Caches mit Durchschreib- und Rückschreibverfahren den Speicher aktuell halten, was Schreibpuffer und Änderungsbits bewirken und wie Write-Allocate und No-Write-Allocate Schreibfehlzugriffe behandeln.
  4. Berechne Trefferraten, mittlere Speicherzugriffszeit und Speicherwartezyklen, berücksichtige sie im CPI-Wert und in der Ausführungszeit und analysiere Systeme mit mehreren Cacheebenen.
    • Berechne die Trefferrate und die mittlere Speicherzugriffszeit
      Berechne Treffer- und Fehlzugriffsraten sowie die mittlere Speicherzugriffszeit eines Caches, auch bei gemischten Befehls- und Datenzugriffen, und vergleiche damit Entwürfe.
    • Berücksichtige Speicherwartezyklen beim CPI-Wert und bei der Ausführungszeit
      Ergänze die CPU-Leistungsgleichung um Speicherwartezyklen, bestimme die Kosten eines Caches für ein Programm und erkläre, warum schnellere Prozessoren stärker unter langsamem Speicher leiden.
    • Analysiere mehrstufige Caches
      Erkläre, warum Prozessoren mehrere Cacheebenen verwenden, unterscheide lokale und globale Fehlzugriffsraten und berechne die mittlere Speicherzugriffszeit und den CPI-Wert für zwei- und dreistufige Hierarchien.
  5. Beschreibe, wie virtuelle Adressen mithilfe einer Seitentabelle in physische Adressen übersetzt werden, warum ein Seitenfehler ein vom Betriebssystem behandelter Fehlzugriff ist und wie der TLB die Übersetzung beschleunigt.
    • Übersetze eine virtuelle Adresse mithilfe einer Seitentabelle
      Erkläre, was virtueller Speicher bietet, zerlege eine virtuelle Adresse in Seitennummer und Offset, übersetze sie mithilfe eines Seitentabelleneintrags und beschreibe, was bei einem Seitenfehler geschieht.
    • Beschleunige die Adressübersetzung mit einem TLB
      Erkläre, wie der Translation Lookaside Buffer Übersetzungen zwischenspeichert, verfolge einen Zugriff durch TLB, Seitentabelle und Cache und erfahre, wie sich Cachezugriff und Übersetzung überlappen.
  6. Organisiere Schleifen und Datenstrukturen so, dass Programme die Speicherhierarchie gut nutzen, und wende Kachelung und Prefetching an, um Daten wiederzuverwenden, während sie im Cache liegen.
    • Ordne Schleifen und Daten so an, dass du Lokalität nutzt
      Ordne Schleifen passend zur Speicherung von Arrays, vermeide ungünstige Schrittweiten und wähle Datenlayouts, die nur nützliche Daten in den Cache bringen.
    • Unterteile Berechnungen in Blöcke und nutze Prefetching
      Strukturiere Schleifen in Blöcke (Kacheln) um, die bei ihrer Wiederverwendung im Cache bleiben, wähle eine Blockgröße und erkläre, wie Hardware- und Software-Prefetching Speicherlatenz verbergen.

Speicherhierarchie und Caches einfach erklärt

6 Kapitel

1

Erkläre, warum Rechner eine Speicherhierarchie nutzen

Programme verwenden einen kleinen Teil ihres Codes und ihrer Daten wiederholt. Diese Wiederverwendung erklärt, warum ein kleiner Cache die meisten Zugriffe bedienen kann, selbst wenn das ganze Programm viel größer ist. Verfolge den Unterschied zwischen zeitlicher Wiederverwendung und benachbarten Adressen, vergleiche die Zellen von SRAM, DRAM und Flash und setze diese Technologien zu Treffern, Fehlzugriffen und Übertragungen durch die Hierarchie in Beziehung. Dasselbe Zugriffsmuster bestimmt später, ob ein Cacheentwurf oder eine Schleifentransformation hilft.

1.1 Wie Programme benachbarte Daten wiederverwenden

Ein Cache funktioniert, weil der nächste Speicherzugriff oft mit einem kürzlich erfolgten Zugriff zusammenhängt. Während eines kurzen Zeitabschnitts nutzen die meisten Programme nur einen kleinen Teil ihres Adressraums. Dieses Muster heißt Lokalität. Ein Cache hält diesen aktiven Teil nahe am Prozessor, wo er Zugriffe schnell bedienen kann.

Wiederverwendung in Zeit und Raum

Zeitliche Lokalität bedeutet, ein Element kurz nach dem Zugriff erneut zu verwenden. Eine Schleife holt die Befehle ihres Körpers wiederholt. Eine laufende Summe wird vielfach gelesen und aktualisiert. Bleiben diese Elemente verfügbar, müssen sie nicht erneut aus einer langsameren Ebene geholt werden.

Räumliche Lokalität bedeutet, auf Elemente an benachbarten Adressen zuzugreifen. Beim Durchlaufen eines Arrays werden benachbarte Elemente gelesen, und Code ohne Verzweigungen holt aufeinanderfolgende Befehle. Ein Cache nutzt dies, indem er bei einem Fehlzugriff einen ganzen Block, auch Cachezeile genannt, holt. Benachbarte Bytes treffen ein, bevor das Programm sie anfordert.

Diese Muster können gemeinsam auftreten. Die Befehle einer Schleife liegen nebeneinander und werden wiederholt ausgeführt, sodass der Befehlsstrom sowohl räumliche als auch zeitliche Lokalität aufweist. Ein genau einmal gelesenes Arrayelement wird zeitlich nicht wiederverwendet, obwohl das Durchlaufen des umgebenden Arrays räumliche Lokalität aufweist.

Blöcke beim Durchlaufen eines Arrays zählen

Betrachte diese C-Schleife mit 4 Byte großen Ganzzahlen und 64 Byte großen Cacheblöcken:

for (int i = 0; i < 1000; i++) {
    sum += a[i];
}

Ein Block fasst 64/4=16 Ganzzahlen. Das Array belegt 1000×4=4000 Byte. Ist sein erstes Element an einer Blockgrenze ausgerichtet, berührt der Durchlauf ⌈4000/64⌉=63 Blöcke: 62 volle Blöcke und einen teilweise gefüllten Block.

In einem zunächst leeren Cache ohne Prefetching oder störende Zugriffe schlägt der erste Zugriff auf jeden Block fehl. Die übrigen Elemente in diesem Block treffen. Das Array verursacht somit 63 Fehlzugriffe bei 1000 Zugriffen, also etwa 6,3 %. Würde man einen Fehlzugriff pro Element zählen, übersähe man alle nützlichen benachbarten Daten, die bei jedem Fehlzugriff mitgeladen werden.

Die Quellcodevariablen sum und i werden häufig wiederverwendet. Ein Compiler hält sie jedoch normalerweise in Registern, sodass ihre Wiederverwendung auf Quellcodeebene keine Datencachezugriffe erzeugen muss. Analysiere die Speicherzugriffe, die das kompilierte Programm ausführt, wenn du den Cacheverkehr abschätzt.

Die Arbeitsmenge muss passen und gemeinsam Platz finden

Die Arbeitsmenge ist die Sammlung der Blöcke, die während eines gewählten Zeitfensters verwendet werden. Passen sie in den Cache und erlauben die Platzierungsregeln, dass sie gemeinsam dort liegen, treffen wiederholte Zugriffe nach dem ersten Laden überwiegend. Das Zeitfenster ist entscheidend: Ein ganzes Programm kann riesig sein, während eine aktive Schleife nur wenige Blöcke nutzt.

Die Kapazität allein reicht nicht aus. Zwei häufig genutzte Blöcke können auf einen direkt abgebildeten Eintrag abgebildet werden und sich gegenseitig verdrängen, während andere Einträge leer bleiben. Eine Arbeitsmenge kann daher ihrer Bytezahl nach passen und dennoch nicht im Cache bleiben.

Verstreute Knoten einer verketteten Liste und zufällige Zugriffe auf eine große Hashtabelle weisen oft geringe räumliche Lokalität auf. Auch das spaltenweise Durchlaufen eines zeilenweise gespeicherten Arrays überspringt viele benachbarte Elemente. Diese Muster laden Bytes, die vor ihrer Verdrängung möglicherweise ungenutzt bleiben. Die Hardware nutzt die durch das Zugriffsmuster vorgegebene Lokalität; durch eine Änderung des Datenlayouts oder der Reihenfolge des Durchlaufens kann ein größerer Teil jedes geholten Blocks nützlich werden.

Wichtige Erkenntnisse

  • Zeitliche Lokalität verwendet ein Element erneut; räumliche Lokalität greift auf benachbarte Adressen zu.
  • Das Holen eines ganzen Blocks ermöglicht Treffer bei späteren Zugriffen auf benachbarte Bytes.
  • Eine Arbeitsmenge muss in die Kapazität passen und nach den Platzierungsregeln des Caches gemeinsam Platz finden.
  • In Registern gehaltene Quellcodevariablen erzeugen keine Datencachezugriffe.

1.2 Speicherzellen, Übertragungen und Zielkonflikte

Bei Speichertechnologien stehen Geschwindigkeit, Dichte, Kosten und dauerhafte Speicherung in einem Zielkonflikt. Der Prozessor braucht schnellen Zugriff auf eine kleine Datenmenge und bezahlbaren Platz für sehr viel mehr. SRAM, DRAM und Flash erfüllen unterschiedliche Teile dieses Bedarfs.

Die Zellen vergleichen
TechnologieSpeicherung eines BitsAuffrischung und StromversorgungHauptaufgabe
SRAMEine stabile Schaltung, typischerweise sechs TransistorenKeine Auffrischung; verliert Daten ohne StromCaches auf dem Chip
DRAMLadung auf einem Kondensator, Zugriff über einen TransistorRegelmäßige Auffrischung; verliert Daten ohne StromHauptspeicher
NAND-FlashEine nichtflüchtige Zelle, deren Zustand elektrisch programmiert wirdBehält Daten ohne Strom; begrenzte SchreibfestigkeitMassenspeicher

Eine SRAM-Zelle ist schnell, belegt aber viel Fläche, wodurch SRAM pro Bit relativ teuer ist. DRAM-Zellen sind kleiner, sodass DRAM mehr Kapazität zu geringeren Kosten pro Bit bietet. Ihre Ladung entweicht. Bei der Auffrischung werden Zeilen innerhalb eines festen Zeitfensters gelesen und wiederhergestellt; DDR4 verwendet bei normalen Temperaturen ein Zeitfenster von 64 ms. „Statisch“ in SRAM bedeutet, dass keine Auffrischung nötig ist, nicht aber, dass die Daten nach einem Stromausfall erhalten bleiben.

Warum die DRAM-Zugriffszeit variiert

DRAM ist in Bänke mit jeweils Zeilen und Spalten unterteilt. Beim Aktivieren einer Zeile wird sie in einen Zeilenpuffer kopiert. Lese- und Schreibzugriffe wählen dann Spalten aus dieser geöffneten Zeile. Um eine andere Zeile derselben Bank zu öffnen, muss die Bank zuerst vorgeladen werden. Ein Zugriff auf eine bereits geöffnete Zeile vermeidet diesen Aufwand für den Zeilenwechsel.

Aufeinanderfolgende Spalten können in einem Burst übertragen werden, was sich zum Holen eines Cacheblocks eignet. Die Verteilung von Anforderungen auf Bänke und Kanäle ermöglicht überlappende Übertragungen. DDR-Speicher überträgt an beiden Taktflanken. Diese Eigenschaften erhöhen die Datenübertragungsrate, ohne die Wartezeit auf die ersten Daten zu beseitigen.

Latenz und Bandbreite unterscheiden

Latenz ist die Verzögerung bis zum Eintreffen der ersten Daten. Bandbreite ist die pro Zeiteinheit übertragene Datenmenge. Eine Schnittstelle mit hoher Bandbreite kann dennoch eine lange anfängliche Verzögerung haben.

Ein DDR5-4800-Kanal mit einem insgesamt 64 Bit breiten Datenpfad überträgt beispielsweise 8 Byte pro Übertragung. Seine Spitzenleistung beträgt 4800×106×8=38,4×109 Byte/s oder 38,4 GB/s. Die dauerhaft von Anwendungen erreichte Bandbreite kann geringer sein, weil Befehle, Zeilenwechsel und andere Arbeiten Zeit beanspruchen.

Wartet eine Anforderung 60 ns und empfängt dann einen 64 Byte großen Block mit 16 GB/s, beträgt die Übertragungsrate 16 Byte/ns. Die Übertragung dauert 64/16=4 ns, insgesamt also etwa 64 ns. Eine Verbesserung allein der Bandbreite verringert den Anteil von 4 ns, nicht die anfänglichen 60 ns.

Flash behält Daten, behandelt Schreibzugriffe aber anders

NAND-Flash liest und programmiert Seiten von mehreren KiB. Um eine programmierte Seite erneut zu verwenden, muss ihr größerer Löschblock gelöscht werden, der viele Seiten enthält. Das Lesen einer Seite dauert typischerweise einige zehn Mikrosekunden, das Programmieren einige hundert Mikrosekunden bis wenige Millisekunden und das Löschen Millisekunden.

Programmier- und Löschzyklen verschleißen die Zellen. Dichtes Mehrbit-Flash unterstützt oft einige Tausend Zyklen, während Einbitzellen etwa 100.000 unterstützen können. Controller verwenden Wear-Leveling, um Schreibzugriffe über die Blöcke zu verteilen.

Zur Einordnung: Ein SRAM-Zugriff dauert ungefähr 1 ns, ein DRAM-Zugriff ungefähr 50–100 ns, ein NAND-Lesezugriff ungefähr 25–100 µs und ein Festplattenzugriff ungefähr 5–10 ms. Tatsächliche Geräte unterscheiden sich. Die Hierarchie kombiniert diese Technologien, weil eine einzelne ihre Vorteile bei Geschwindigkeit, Kapazität und Preis nicht zugleich bieten kann.

Wichtige Erkenntnisse

  • SRAM und DRAM sind flüchtig; Flash behält Daten ohne Strom.
  • Die DRAM-Auffrischung stellt entweichende Ladung wieder her, während Zeilenpuffer und Bursts die Zugriffseffizienz verbessern.
  • Latenz misst die anfängliche Wartezeit; Bandbreite misst die Übertragungsrate.
  • Flash programmiert Seiten und löscht größere Blöcke.
  • Wear-Leveling verteilt den Verschleiß durch Programmieren und Löschen auf die Flash-Blöcke.

1.3 Verfolge einen Zugriff durch die Hierarchie

Die Speicherhierarchie platziert kleinen, schnellen Speicher nahe am Prozessor und zunehmend größeren Speicher weiter entfernt. Lokalität ermöglicht es den kleinen Ebenen, einen großen Anteil der Anforderungen zu bedienen, während die unteren Ebenen Kapazität bereitstellen.

Ebenen und Übertragungseinheiten

Ein typischer Weg führt über Register, L1, L2, L3, Hauptspeicher und Massenspeicher. L1 hat üblicherweise getrennte Befehls- und Datencaches von jeweils etwa 32–64 KiB pro Kern. L2 umfasst oft einige hundert KiB bis wenige MiB pro Kern, während L3 häufig gemeinsam genutzt wird und mehrere bis einige zehn MiB fasst. Der Hauptspeicher fasst viele GiB, der Massenspeicher mehrere hundert GB oder mehr. Entwürfe unterscheiden sich in Größe und gemeinsamer Nutzung.

Bei einem Prozessor mit etwa 3 GHz betragen typische Ladelatenzen für L1 etwa 4–5 Taktzyklen, für L2 12–15, für L3 30–50 und für DRAM 200–300. Ein L1-Cache kann in jedem Taktzyklus eine neue Anforderung annehmen, selbst wenn eine Anforderung mehrere Taktzyklen bis zum Abschluss benötigt: Durchsatz und Latenz beschreiben unterschiedliche Eigenschaften.

Daten werden durch Caches in Blöcken übertragen, die häufig 64 Byte groß sind. Virtueller Speicher verwendet Seiten, häufig 4 KiB groß, wenn Seiteninhalte zwischen Haupt- und Massenspeicher übertragen werden. Eine Cachezeile und eine Seite dienen auf unterschiedlichen Größenskalen ähnlichen Gruppierungszwecken; sie sind nicht dieselbe Übertragungseinheit.

Treffer, Fehlzugriffe und Zeitbedarf

Ein Treffer bedeutet, dass eine Ebene die angeforderten Daten enthält. Ein Fehlzugriff bedeutet, dass sie die Daten von einer unteren Ebene holen muss. Beide Begriffe beziehen sich auf die geprüfte Ebene: Auf einen L1-Fehlzugriff kann dennoch ein L2-Treffer folgen.

Die Trefferrate ist die Anzahl der Treffer geteilt durch die Anzahl der Zugriffe, und die Fehlzugriffsrate ist eins minus Trefferrate. Die Trefferzeit umfasst die Prüfung der Ebene und die Entscheidung, ob die Anforderung trifft. Die Fehlzugriffsverzögerung ist die zusätzliche Zeit, die bei einem Fehlzugriff benötigt wird, um den Block zu holen und bereitzustellen.

Angenommen, ein vereinfachter Cache hat eine Trefferzeit von 1 Taktzyklus, eine Trefferrate von 97 % und eine zusätzliche Fehlzugriffsverzögerung von 100 Taktzyklen. Bei jedem Zugriff fällt 1 Taktzyklus an, bei 3 % kommen weitere 100 hinzu:

1+0,03×100=4 Taktzyklen.

Ein Fehlzugriff dauert in diesem Beispiel 101 Taktzyklen. Würde man 100 als gesamte Fehlzugriffszeit verwenden, würde die Trefferprüfung nicht einheitlich berechnet. Selbst bei einer hohen Trefferrate machen sich teure Fehlzugriffe im Mittel bemerkbar.

Wer verwaltet die einzelnen Ebenen?

Der Compiler weist geeignete Werte Registern zu. Die Cachehardware verschiebt Blöcke automatisch, während Lade- und Speicherbefehle sowie das Holen von Befehlen ausgeführt werden. Programme nennen Adressen; sie wählen keine Cacheeinträge aus. Das Betriebssystem verwaltet mit Hardwareunterstützung die Abbildungen des virtuellen Speichers und behandelt Seiten, die in den Hauptspeicher gebracht werden müssen.

Die Trennung von Befehlen und Daten in L1 ermöglicht es einer Pipeline, einen Befehl zu holen und gleichzeitig auf Daten zuzugreifen, ohne um denselben Cacheport zu konkurrieren. Untere Caches sind meist vereinheitlicht und speichern sowohl Befehls- als auch Datenblöcke.

Manche Hierarchien sind inklusiv: Von einem oben vorhandenen Block gibt es auch unten eine Kopie. Andere sind exklusiv oder nichtinklusiv, sodass eine Kopie in jedem unteren Cache nicht garantiert ist. Zeichne eine Hierarchie als Such- und Übertragungsweg, nicht als Zusicherung, dass alle Ebenen identische Teilmengen enthalten.

Ein größerer L1-Cache kann Fehlzugriffe verringern, aber Zugriffsverzögerung und Energiebedarf erhöhen. Größere untere Caches ermöglichen es, L1 schnell zu halten und zugleich viele seiner Fehlzugriffe vor dem DRAM abzufangen. Beurteile diesen Zielkonflikt anhand der Zugriffszeit, nicht allein anhand der Kapazität.

Wichtige Erkenntnisse

  • Ein Treffer oder Fehlzugriff bezieht sich auf die jeweils geprüfte Ebene.
  • Die Trefferzeit fällt bei jeder Suche an; die Fehlzugriffsverzögerung ist die zusätzliche Zeit bei Fehlzugriffen.
  • Caches übertragen Blöcke, während virtueller Speicher Seiten verwendet.
  • Getrennte L1-Befehls- und Datencaches ermöglichen gleichzeitige Pipelinezugriffe.
  • Cache-Inklusion ist eine Entwurfsentscheidung.
  • Eine größere Kapazität muss gegen Trefferzeit und Energiebedarf abgewogen werden.
2

Finde Daten in direkt abgebildeten und satzassoziativen Caches

Eine Speicheradresse muss einem Cache zeigen, wo er suchen und welche Bytes er zurückgeben soll. Zerlege Adressen in Felder, verfolge, wie Anforderungen Blöcke ersetzen, und gib dann jedem Block durch Sätze und Wege mehr Platzierungsmöglichkeiten. Kleine Zugriffsprotokolle machen die Hardwareregeln sichtbar: Ein anderes Byte kann in einem geladenen Block treffen, während ein wiederholt verwendeter Block nach einem Konflikt einen Fehlzugriff verursachen kann. Diese Suchregeln bestimmen auch, wie viele Tags und Steuerbits der Cache speichern muss.

2.1 Bestimme Tag, Index und Offset

Eine Byteadresse bezeichnet ein Byte im Speicher. Ein Cache holt einen ganzen Block, daher wird bei der Suche zuerst dieser Block bestimmt und anschließend werden die angeforderten Bytes darin ausgewählt. In einem direkt abgebildeten Cache hat jeder Block genau einen möglichen Eintrag.

Die Adresse nach Zweck aufteilen

Bei einer Blockgröße von 2b Byte bilden die niederwertigen b Adressbits den Offset. Teilt man die Byteadresse durch die Blockgröße und verwirft den Rest, erhält man die Blockadresse. Der Rest ist der Offset.

Hat der Cache E Einträge, ist der Index des Eintrags

Index=Blockadresse mod E.

Ist die Anzahl der Einträge eine Zweierpotenz, besteht der Index aus der Gruppe von Adressbits unmittelbar oberhalb des Offsets. Die verbleibenden hohen Bits bilden das Tag, das dem Cache angibt, welcher der vielen Blöcke mit demselben Index vorhanden ist.

Die Reihenfolge der Felder von den höchst- zu den niederwertigen Bits ist Tag | Index | Offset. Bei einer Adressbreite von A Bits gilt:

b=log⁡2(Blockgro¨ße in Byte),s=log⁡2E,t=A−s−b.

Verwende für die Indexberechnung die Anzahl der Einträge. Würdest du den Logarithmus der Kapazität in Byte bilden, würdest du die Offset-Bits ein zweites Mal zählen.

Ein Beispiel mit 16 KiB durchrechnen

Ein direkt abgebildeter Cache mit 16 KiB und 64 Byte großen Blöcken hat 16384/64=256 Einträge. Bei 32-Bit-Adressen belegt der Offset 6 Bit, der Index 8 Bit und das Tag 32−8−6=18 Bit.

Für die Byteadresse 0x1234ABCD ergeben die niederwertigen 6 Bits den Offset 13 oder 0x0D. Entfernt man diese Bits, erhält man die Blockadresse 0x48D2AF. Ihre niederwertigen 8 Bits sind 0xAF, der Index ist also 175. Die verbleibenden Bits ergeben das Tag 0x48D2.

Die Byteadresse lässt sich aus diesen Feldern rekonstruieren: Hänge das Tag, den 8-Bit-Index und den 6-Bit-Offset aneinander. Die Feldbreiten sind wichtig, weil eine Hexadezimalziffer 4 Bit darstellt; die Grenzen müssen nicht zwischen Hexadezimalziffern liegen.

Ein passendes Tag braucht einen gültigen Eintrag

Jeder Eintrag speichert Daten, ein Tag und ein Gültigkeitsbit. Der Index wählt den Eintrag aus. Ein Treffer erfordert sowohl ein gesetztes Gültigkeitsbit als auch die Übereinstimmung des gespeicherten Tags mit dem angeforderten Tag. Beim Start kann ein Eintrag beliebige Bits enthalten; das Gültigkeitsbit verhindert, dass diese Bits für einen geladenen Block gehalten werden.

Sobald der Block vorhanden ist, treffen auch Zugriffe auf andere Bytes in diesem Block. Ein Treffer erfordert nicht dieselbe Byteadresse, mit der der Block geholt wurde.

Metadaten getrennt zählen

Die angegebene Cachekapazität zählt normalerweise nur Daten. Hier enthält jeder Eintrag 512 Datenbits, 18 Tag-Bits und 1 Gültigkeitsbit, also 531 Bits. Der gesamte Speicherbedarf beträgt

256×531=135936 Bits.

Die Daten allein benötigen 131072 Bits. Tags und Gültigkeitsbits fügen 4864 Bits hinzu, etwa 3,7 % des Datenspeichers. Ein Entwurf mit Rückschreibverfahren benötigt außerdem Änderungsbits; komplexere Entwürfe benötigen weitere Steuerzustände.

Der Index verwendet niederwertige Blockadressbits, sodass aufeinanderfolgende Blöcke auf aufeinanderfolgende Einträge verteilt werden. Eine breitere Adresse lässt die Breite von Offset und Index unverändert, wenn Kapazität und Blockgröße gleich bleiben; die zusätzlichen Bits verlängern das Tag.

Wichtige Erkenntnisse

  • Berechne die Anzahl der Einträge aus der Datenkapazität geteilt durch die Blockgröße.
  • Die niederwertigen Adressbits wählen den Byteoffset; die nächsten Bits wählen den Eintrag.
  • Ein Treffer erfordert einen gültigen Eintrag und ein übereinstimmendes Tag.
  • Die angegebene Datenkapazität umfasst keine Tags und Steuerbits.

2.2 Verfolge einen direkt abgebildeten Cache

Ein Cache-Zugriffsprotokoll hält fest, wie jeder Zugriff die gespeicherten Blöcke verändert. Führe für jeden Eintrag einen eigenen Zustand und aktualisiere ihn unmittelbar nach jedem Fehlzugriff. Die nächste Anforderung verwendet den aktualisierten Cache und nicht den Cache im Anfangszustand.

Das Zugriffsprotokoll vorbereiten

Nimm einen direkt abgebildeten Cache mit 64 Byte und vier Einträgen zu je 16 Byte. Er ist anfangs leer. Teile für jede Byteadresse durch 16, um den Block zu finden, und berechne dann Block modulo 4 für den Index. Das Tag ist die durch 4 geteilte Blocknummer, wobei der Nachkommateil verworfen wird. Es gibt 4 Offset-Bits und 2 Index-Bits.

Prüfe bei einem Lesezugriff den ausgewählten Eintrag. Ist er gültig und stimmt das Tag überein, notiere einen Treffer. Andernfalls notiere einen Fehlzugriff, ersetze den Block und das Tag dieses Eintrags und setze sein Gültigkeitsbit. In einem direkt abgebildeten Cache gibt es keine Wahl bei der Ersetzung.

Alle acht Zugriffe verfolgen
ByteadresseBlockIndexTagErgebnisVerbleibender Block im gewählten Eintrag
0x00000Fehlzugriff0
0x04000Treffer0
0x40401Fehlzugriff4
0x00000Fehlzugriff0
0x14110Fehlzugriff1
0x44401Fehlzugriff4
0x08000Fehlzugriff0
0x84802Fehlzugriff8

Der erste Zugriff füllt Eintrag 0 mit Block 0. Die nächste Adresse, 0x04, liegt noch innerhalb dieses 16-Byte-Blocks und trifft daher, obwohl sie ein anderes Byte bezeichnet. 0x40 gehört zu Block 4. Er hat denselben Index wie Block 0, aber ein anderes Tag und ersetzt daher Block 0.

Das zweite 0x00 schlägt daher fehl. Die frühere Verwendung allein garantiert keinen Treffer: Der Block muss noch vorhanden sein. Die Anforderung an 0x14 lädt Block 1 in Eintrag 1 und lässt Eintrag 0 unverändert.

Anschließend lädt 0x44 Block 4 erneut in Eintrag 0. 0x08 benötigt Block 0 und verdrängt Block 4. Schließlich lädt 0x84 Block 8 in denselben Eintrag. Am Ende enthält Eintrag 0 Block 8 und Eintrag 1 enthält Block 1; die Einträge 2 und 3 bleiben ungültig.

Das Verhalten deuten

Es gibt einen Treffer und sieben Fehlzugriffe, die Trefferrate beträgt also 1/8=12,5%. Die Blöcke 0, 4 und 8 konkurrieren um Eintrag 0. Der Cache hat vier Einträge, doch dieses Zugriffsmuster nutzt nur zwei davon. Die wiederholten Verdrängungen entstehen durch Abbildungskonflikte, nicht durch einen Mangel an Gesamtspeicher für die vier verschiedenen Blöcke.

Das Laden eines Blocks macht alle Bytes dieses Blocks verfügbar. Bei einem sequenziellen Durchlauf kann ein Fehlzugriff daher viele folgende Elemente bedienen. Hier beseitigen die konkurrierenden Zugriffe diesen Vorteil wiederholt, bevor das nächste benachbarte Byte angefordert wird.

Für ein zuverlässiges Zugriffsprotokoll benenne Byteadressen und Blocknummern ausdrücklich. Wendet man Modulo 4 direkt auf die Byteadresse an, überspringt man die Division durch die Blockgröße und leitet Anforderungen an die falschen Einträge. Halte die Ersetzung auch dann fest, wenn der neue Block zuvor schon geladen wurde: Jeder Fehlzugriff lädt den angeforderten Block und sein Tag in den ausgewählten Eintrag.

Wichtige Erkenntnisse

  • Aktualisiere den Cacheinhalt nach jedem Fehlzugriff.
  • Unterschiedliche Byteadressen innerhalb eines vorhandenen Blocks treffen.
  • Ein zuvor aufgerufener Block kann nach seiner Verdrängung einen Fehlzugriff verursachen.
  • Abbildungskonflikte können Fehlzugriffe verursachen, während andere Einträge leer bleiben.
  • Das Beispiel hat einen Treffer bei acht Zugriffen, eine Trefferrate von 12,5 %.

2.3 Gib Blöcken mehr Platzierungsmöglichkeiten

Ein satzassoziativer Cache bietet einem Block mehrere mögliche Einträge, ohne den gesamten Cache zu durchsuchen. Der Index wählt einen Satz aus, und der Block kann jeden Weg in diesem Satz belegen. Das verringert Konflikte zwischen Blöcken mit demselben Index.

Sätze und Felder berechnen

Für die Datenkapazität C, die Blockgröße B und die Assoziativität n gilt:

Blo¨cke=C/B,Sa¨tze=C/(Bn).

Der Satzindex ist die Blockadresse modulo Anzahl der Sätze. Der Offset hängt weiterhin nur von der Blockgröße ab. Das Tag enthält die verbleibenden hohen Bits.

Ein 8-fach assoziativer Cache mit 32 KiB und 64 Byte großen Blöcken hat 512 Blöcke und 64 Sätze. Bei 32-Bit-Adressen sind Offset, Index und Tag 6, 6 und 20 Bit breit. Die Adresse 0x1234ABCD hat den Offset 13, den Satz 47 und das Tag 0x1234A.

Bei fester Kapazität und Blockgröße halbiert eine Verdopplung der Assoziativität die Anzahl der Sätze. Ein Index-Bit wird zu einem Tag-Bit; die Datenkapazität wächst nicht.

OrganisationZulässige PlatzierungIndex
Direkt abgebildetEin EintragWählt diesen Eintrag
n-fach assoziativJeder der n Wege in einem SatzWählt diesen Satz
VollassoziativJeder Eintrag im CacheKein Indexfeld

Bei der Suche wird das Tag parallel mit allen gültigen Tags im gewählten Satz verglichen. Ein Weg mit passendem Tag liefert die Daten über einen Multiplexer. Mehr Wege benötigen mehr Vergleiche und Auswahlhardware, was Trefferzeit und Energiebedarf erhöhen kann.

Einen Block erst ersetzen, wenn der Satz voll ist

Verwende zuerst einen ungültigen Weg. Sind alle Wege belegt, verdrängt LRU den Block, dessen letzter Zugriff am längsten zurückliegt. Aktualisiere die Information über die letzte Nutzung sowohl bei Treffern als auch beim Laden. Ein 2-fach assoziativer Satz benötigt nur ein Bit, um seinen LRU-Weg festzuhalten; größere Sätze verwenden oft Pseudo-LRU-Näherungen.

FIFO verdrängt den zuerst geladenen Block, selbst wenn kürzlich darauf zugegriffen wurde. Die zufällige Ersetzung wählt einen zu verdrängenden Block, ohne die vollständige Nutzungsreihenfolge zu speichern. Sie ist einfach und kann in großen Caches eine ähnliche Leistung wie LRU erreichen.

Das kleine Zugriffsprotokoll mit zwei Wegen erneut betrachten

Der Cache mit 64 Byte und 16 Byte großen Blöcken hat nun zwei Sätze mit je zwei Wegen. Die Blöcke 0, 4 und 8 werden auf Satz 0 abgebildet, Block 1 auf Satz 1. Für 0x00, 0x04, 0x40, 0x00, 0x14, 0x44, 0x08, 0x84 lauten die Ergebnisse: Fehlzugriff, Treffer, Fehlzugriff, Treffer, Fehlzugriff, Treffer, Treffer, Fehlzugriff.

Die Blöcke 0 und 4 können gleichzeitig im Cache liegen, sodass die wiederholten Zugriffe auf sie treffen. Unmittelbar vor dem letzten Zugriff wurde Block 0 vor kürzerer Zeit verwendet als Block 4. Das Laden von Block 8 verdrängt bei LRU den Block 4. Vier von acht Zugriffen treffen, gegenüber einem bei der direkt abgebildeten Variante.

Assoziativität kann weder obligatorische Fehlzugriffe beseitigen noch eine Arbeitsmenge in den Cache passen lassen, die größer als seine Kapazität ist. Sie kann auch keine Konflikte verhindern, wenn mehr als n häufig genutzte Blöcke um einen n-fach assoziativen Satz konkurrieren. Ein wiederholter Zyklus aus n+1 solchen Blöcken kann dazu führen, dass LRU jedes Mal einen Fehlzugriff verzeichnet. Padding von Arrays kann ihre Satzzuordnung verändern; mehr Wege sind nur eine mögliche Reaktion auf ein Konfliktproblem.

Wichtige Erkenntnisse

  • Die Anzahl der Sätze ist die Datenkapazität geteilt durch Blockgröße und Anzahl der Wege.
  • Eine höhere Assoziativität verändert die Flexibilität der Platzierung, nicht die Datenkapazität.
  • LRU berücksichtigt Zugriffe; FIFO berücksichtigt die Reihenfolge des Einfügens.
  • Fülle ungültige Wege, bevor du gültige Blöcke ersetzt.
  • Vollassoziative Caches haben kein Indexfeld, aber weiterhin Kaltstart- und kapazitätsbedingte Fehlzugriffe.
  • Mehr Wege können konfliktbedingte Fehlzugriffe verringern, erhöhen aber den Hardware- und Zeitaufwand.
3

Erkläre Cache-Fehlzugriffe und Schreibstrategien

Ein Fehlzugriff kann beim ersten Zugriff entstehen, durch begrenzte Kapazität oder weil Blöcke um dieselben Plätze konkurrieren. Die Ursache zu erkennen hilft zu erklären, welche Entwurfsänderungen ihn verringern können. Speicherbefehle bringen ein zweites Problem mit sich: Die Hierarchie muss entscheiden, wann veränderte Daten die nächste Ebene erreichen und was geschieht, wenn der Block fehlt. Verfolge die Behandlung von Lesefehlzugriffen, Schreibstrategien, Puffer und die Verdrängung veränderter Blöcke, um den Cachezustand mit dem entstehenden Datenverkehr und den Verzögerungen zu verknüpfen.

3.1 Erkläre die Ursache eines Fehlzugriffs

Ein Cache-Fehlzugriff ist ein Ereignis mit einem Ablauf und einer Ursache. Der Ablauf beschreibt, wie die Anforderung bedient wird. Die Ursache erklärt, warum der benötigte Block fehlte und welche Entwurfsänderung helfen könnte.

Einen Lesefehlzugriff behandeln

In einer einfachen Pipeline mit Ausführung in Befehlsreihenfolge erkennt der Cache einen ungültigen Eintrag oder ein nicht übereinstimmendes Tag, und der Prozessor hält an. Der Cache fordert den Block von der nächsten Ebene an. Ist der zur Verdrängung ausgewählte Block verändert, müssen seine geänderten Daten durch Zurückschreiben erhalten werden. Der eintreffende Block wird zusammen mit seinem Tag und Gültigkeitsbit eingetragen, und der wartende Zugriff wird abgeschlossen. Ebenso wartet ein Fehlzugriff im Befehlscache auf den Block des Befehls und holt den Befehl anschließend erneut.

Critical Word First fordert das benötigte Wort im zurückkehrenden Block zuerst an. Der frühzeitige Neustart ermöglicht die Fortsetzung der Ausführung, sobald dieses Wort eintrifft. Ein nichtblockierender Cache kann andere Treffer bedienen und ausstehende Fehlzugriffe verfolgen, während ein Prozessor mit Ausführung außerhalb der Befehlsreihenfolge unabhängige Arbeit erledigt. Diese Mechanismen verringern die Wartezeit; sie beseitigen die ursprüngliche Datenabhängigkeit nicht.

Die drei C verwenden
FehlzugriffsklasseWarum der Block fehltTest zur Einordnung
ObligatorischDies ist der erste Zugriff auf den BlockEr würde selbst bei unbegrenzter Kapazität fehlschlagen
KapazitätsbedingtDie aktiven Blöcke überschreiten den verfügbaren PlatzAuch ein vollassoziativer LRU-Cache gleicher Größe verzeichnet einen Fehlzugriff
KonfliktbedingtPlatzierungsbeschränkungen haben den Block verdrängtEin vollassoziativer LRU-Cache gleicher Größe verzeichnet einen Treffer

Prüfe zuerst, ob es sich um den ersten Zugriff handelt. Der erste Zugriff auf einen Block ist obligatorisch, auch wenn sein Zieleintrag bereits belegt ist. Vergleiche bei späteren Fehlzugriffen den tatsächlichen Cache mit einem vollassoziativen LRU-Cache gleicher Datenkapazität und Blockgröße, wobei beide dieselbe Zugriffsfolge erhalten.

Im früheren Zugriffsprotokoll mit vier Einträgen verursachen die Blöcke 0, 4, 1 und 8 jeweils einen obligatorischen Fehlzugriff. Der direkt abgebildete Cache verzeichnet auch bei den wiederholten Zugriffen auf die Blöcke 0 und 4 Fehlzugriffe. Ein vollassoziativer Cache mit vier Einträgen kann alle vier verschiedenen Blöcke halten, sodass diese drei erneuten Fehlzugriffe konfliktbedingt sind. Kapazitätsbedingte Fehlzugriffe gibt es nicht.

Eine Änderung wählen, die die Ursache angeht

Eine größere Kapazität kann eine größere Arbeitsmenge halten. Eine höhere Assoziativität kann ermöglichen, dass konkurrierende Blöcke gemeinsam im Cache liegen. Eine größere Blockgröße kann räumliche Lokalität nutzen, indem bei jedem Laden mehr nützliche benachbarte Daten mitgebracht werden.

Die Blockgröße hat gegenläufige Auswirkungen. Bei fester Datenkapazität bedeuten größere Blöcke weniger gleichzeitig gespeicherte Blöcke. Ungenutzte Bytes belegen Cacheplatz, andere nützliche Blöcke können verdrängt werden und jede Übertragung kann länger dauern. Die Fehlzugriffsrate fällt bei wachsender Blockgröße häufig zunächst und steigt dann, wenn diese Kosten den Nutzen räumlicher Lokalität überwiegen.

Ein größerer Cache kann auch eine längere Suchzeit haben, und zusätzliche Wege benötigen mehr Vergleichshardware. Beurteile Änderungen anhand der mittleren Zugriffszeit einschließlich Trefferzeit und Fehlzugriffsverzögerung, statt anzunehmen, dass eine niedrigere Fehlzugriffsrate einen schnelleren Entwurf garantiert.

In Mehrkernsystemen kann die Invalidierung nach einem Schreibzugriff eines anderen Kerns kohärenzbedingte Fehlzugriffe verursachen. Prefetching kann einen erstmals benötigten Block vor dem anfordernden Zugriff laden und so einen Fehlzugriff verbergen, den zusätzliche Kapazität allein nicht vermeiden kann.

Wichtige Erkenntnisse

  • Ordne erste Zugriffe als obligatorisch ein, bevor du andere Ursachen prüfst.
  • Verwende einen vollassoziativen LRU-Cache gleicher Größe, um kapazitätsbedingte von konfliktbedingten Fehlzugriffen zu unterscheiden.
  • Größere Blöcke bieten mehr nutzbare räumliche Lokalität, aber weniger gleichzeitig gespeicherte Blöcke und längere Übertragungen.
  • Frühzeitiger Neustart, Critical Word First und nichtblockierende Caches verringern die Wartezeit auf unterschiedliche Weise.
  • Vergleiche die vollständige Zugriffszeit, wenn du eine Verbesserung der Fehlzugriffsrate beurteilst.

3.2 Bestimme, wann Speicherbefehle die nächste Ebene erreichen

Ein Speicherbefehl verändert einen Wert, daher braucht die Hierarchie eine Regel, um diese Änderung nach unten weiterzugeben. Dabei sind zwei Entscheidungen getrennt zu treffen: Was geschieht bei einem Treffer des Speicherbefehls und was bei einem Fehlzugriff?

Durchschreib- und Rückschreibverfahren
StrategieAktion bei einem SchreibtrefferAuswirkung auf die nächste Ebene
DurchschreibverfahrenCache aktualisieren und Speicherbefehl nach unten sendenJeder Speicherbefehl erzeugt eine Aktualisierung der unteren Ebene
RückschreibverfahrenCache aktualisieren und seinen Block als verändert markierenEin veränderter Block wird bei seiner Verdrängung nach unten gesendet

Ein Änderungsbit hält fest, dass ein Block beim Rückschreibverfahren Änderungen enthält, die noch nicht in die nächste Ebene geschrieben wurden. Ein unveränderter zu verdrängender Block muss nicht zurückgeschrieben werden. Bei einem veränderten müssen die geänderten Daten erhalten werden, bevor sein Eintrag wiederverwendet werden kann. Die Ladebefehle des Prozessors erhalten den neuen Wert aus dem Cache, auch wenn die untere Kopie noch älter ist.

Bei 100 Speicherbefehlen auf eine zwischengespeicherte 4 Byte große Variable sendet das Durchschreibverfahren ohne Zusammenfassung 100 Schreibzugriffe oder 400 Byte Nutzdaten. Das Rückschreibverfahren kann diese Änderungen bei der Verdrängung zu einem Schreibzugriff auf einen 64 Byte großen Block zusammenfassen. Dieser Vergleich zählt die Nutzdaten der Aktualisierung und lässt das anfängliche Laden und den Protokollaufwand aus.

Der Nutzen hängt von der Wiederverwendung ab. Wiederholte Schreibzugriffe auf einen Block geben dem Rückschreibverfahren die Möglichkeit, Aktualisierungen zusammenzufassen; über viele Blöcke verstreute Schreibzugriffe können zur Verdrängung vieler veränderter Blöcke führen. Untere Caches verwenden häufig das Rückschreibverfahren, um den Datenverkehr zum DRAM zu begrenzen. L1-Datencaches können beide Strategien verwenden.

Ein Schreibpuffer verbirgt Wartezeit, nicht Datenverkehr

Ein Schreibpuffer stellt ausstehende Schreibzugriffe auf die untere Ebene in eine Warteschlange. Beim Durchschreibverfahren kann der Prozessor fortfahren, sobald ein Speicherbefehl im Puffer steht, statt auf den Abschluss durch den unteren Speicher zu warten. Die untere Ebene holt auf, während die gepufferten Speicherbefehle abgearbeitet werden; sie kann vorübergehend hinter dem zwischengespeicherten Wert zurückbleiben.

Der Puffer hat eine endliche Kapazität. Treffen Speicherbefehle lange genug schneller ein, als die untere Ebene sie annimmt, füllt er sich und der Prozessor hält an. Ein Puffer verändert, wann der Prozessor wartet, nicht die dauerhaft verfügbare Bandbreite des Ziels.

Ohne Pufferung oder Überlappung wird aus einem Basis-CPI-Wert von 1 der Wert 1+0,1×100=11, wenn 10 % der Befehle speichern und jeder Speicherbefehl 100 Wartezyklen hinzufügt. Pufferung kann einen großen Teil dieser Verzögerung verbergen, wenn das Ziel im Mittel Schritt hält.

Einen Schreibfehlzugriff gesondert behandeln

Das Write-Allocate-Verfahren holt den fehlenden Block in den Cache und führt dann den Speicherbefehl aus. Es passt gut zum Rückschreibverfahren, weil spätere Zugriffe und Schreibvorgänge diesen Block wiederverwenden können. Das No-Write-Allocate-Verfahren sendet den Speicherbefehl nach unten, ohne diesen Cache zu füllen. Es passt gut zum Durchschreibverfahren und kann vermeiden, dass bei einer einmaligen Ausgabefolge nützliche Blöcke verdrängt werden.

Diese Strategien werden unabhängig voneinander gewählt. Dass ein Cache das Durchschreibverfahren nutzt, sagt für sich allein nicht, ob bei einem Schreibfehlzugriff eine Cachezeile angelegt wird; ein Zugriffsprotokoll muss beide Strategien angeben.

Ein Fehlzugriff beim Rückschreibverfahren, der einen veränderten Block zur Verdrängung auswählt, umfasst neben dem eingehenden Laden auch ausgehende Daten. Das erhöht die Verzögerung, sofern Puffer oder Überlappung nicht einen Teil der Arbeit verbergen. Auch andere Kerne und Ein-/Ausgabegeräte benötigen eine konsistente Sicht, wenn der untere Speicher veraltet ist. Kohärenz- und Systemmechanismen koordinieren diese Sichtbarkeit; ein Änderungsbit allein hält nur ausstehende Änderungen fest.

Wichtige Erkenntnisse

  • Das Durchschreibverfahren sendet jeden Speicherbefehl nach unten; das Rückschreibverfahren verzögert Änderungen bis zum Zurückschreiben des veränderten Blocks.
  • Ein Änderungsbit unterscheidet veränderte von unveränderten Blöcken.
  • Schreibpuffer verbergen Latenz, bis sie voll sind; sie schaffen keine Bandbreite.
  • Write-Allocate und No-Write-Allocate legen das Verhalten bei Schreibfehlzugriffen unabhängig von der Strategie bei Treffern fest.
  • Die Verdrängung eines veränderten Blocks fügt der Behandlung eines Fehlzugriffs ausgehenden Datenverkehr hinzu.
  • Beim gepufferten Durchschreibverfahren kann die untere Ebene vorübergehend zurückliegen.
4

Berechne die Leistungskennwerte eines Caches

Ein Cacheentwurf ist nur nützlich, wenn seine Treffer und Fehlzugriffe zu einer besseren Ausführungszeit führen. Kombiniere Suchzeit, Fehlzugriffshäufigkeit und zusätzliche Fehlzugriffsverzögerung und setze dann die Zugriffskosten zu den Wartezyklen pro Befehl in Beziehung. Trenne Befehls- und Datenverkehr, rechne Taktzyklen und Zeiten einheitlich um und verschachtele die Kosten unterer Caches mithilfe des Anteils der Anforderungen, der jede Ebene erreicht. Diese Berechnungen zeigen, warum eine niedrigere Fehlzugriffsrate oder ein schnellerer Takt weniger Nutzen bringen kann als erwartet.

4.1 Berechne die mittlere Speicherzugriffszeit

Eine hohe Trefferrate ist nützlich, aber kein vollständiges Leistungsmaß. Wenige teure Fehlzugriffe können den Mittelwert bestimmen, und ein Entwurf, der mehr Fehlzugriffe vermeidet, kann dennoch unterliegen, wenn seine Suche zu langsam wird.

Mit Raten und Zeitdefinitionen beginnen
Trefferrate=TrefferZugriffe,Fehlzugriffsrate=FehlzugriffeZugriffe.

Die beiden Anteile ergeben zusammen eins. Wandle Prozentangaben vor dem Multiplizieren in Anteile um: 5 % sind 0,05.

Die mittlere Speicherzugriffszeit oder AMAT ist

AMAT=Trefferzeit+Fehlzugriffsrate×Fehlzugriffsverzo¨gerung.

Jede Anforderung prüft den Cache, auch Anforderungen, die fehlschlagen. Die Fehlzugriffsverzögerung ist die zusätzliche Verzögerung nach dieser Suche. Gleichwertig kannst du die Trefferzeit mit dem Trefferanteil und die gesamte Fehlzugriffszeit mit dem Fehlzugriffsanteil gewichten; durch Ausmultiplizieren ergibt sich dieselbe Formel.

Bei einer Trefferzeit von 1 Taktzyklus, 5 % Fehlzugriffen und einer zusätzlichen Verzögerung von 100 Taktzyklen beträgt die AMAT 1+0,05×100=6 Taktzyklen. Bei 2 GHz dauert jeder Taktzyklus 0,5 ns, das sind also 3 ns. Rechne entweder vollständig in Taktzyklen oder vollständig in Zeiteinheiten und wandle bei Bedarf das Endergebnis um.

Vollständige Entwürfe vergleichen

Cache A hat eine Suchzeit von 1,0 ns und 5 % Fehlzugriffe. Cache B hat eine Suchzeit von 1,2 ns und 3,5 % Fehlzugriffe. Bei einer Fehlzugriffsverzögerung von 50 ns gilt:

A=1+0,05×50=3,5 ns, B=1,2+0,035×50=2,95 ns.

B gewinnt, weil die vermiedenen teuren Fehlzugriffe seine langsamere Suche mehr als ausgleichen. Sinkt die Verzögerung auf 10 ns, benötigt A 1,5 ns und B 1,55 ns. Nun gewinnt A. Der Nutzen einer verbesserten Fehlzugriffsrate ist proportional zur vermiedenen Verzögerung.

Befehls- und Datenzugriffe richtig gewichten

Angenommen, jeder Befehl erzeugt im Mittel einen Befehlsabruf und 0,3 Datenzugriffe. Die Fehlzugriffsrate für Befehle beträgt 2 % und die für Daten 4 %. Bei 100 Befehlen gibt es 100 Befehlsabrufe und 30 Datenzugriffe. Erwartet werden 100×0,02+30×0,04=3,2 Fehlzugriffe bei 130 Zugriffen.

Der kombinierte Fehlzugriffsanteil beträgt daher 0,02+0,3×0,041,3. Bei gleichen Trefferzeiten von 1 Taktzyklus und Fehlzugriffsverzögerungen von 100 Taktzyklen beträgt die AMAT etwa 3,46 Taktzyklen pro Speicherzugriff. Würde man 2 % und 4 % direkt mitteln, erhielten die beiden Zugriffsarten fälschlich dasselbe Gewicht.

Eine Übertragungsverzögerung abschätzen

Eine Blockanforderung kann eine anfängliche Latenz und anschließend eine Übertragungszeit umfassen. Bei 60 ns Latenz, einer 64 Byte großen Cachezeile und 16 GB/s Bandbreite dauert die Übertragung 4 ns, sodass die zusätzliche Verzögerung etwa 64 ns beträgt. Bei 3 GHz gibt es 3 Taktzyklen/ns, das sind also 192 Taktzyklen.

Prüfe, was die Zeitangabe einer Aufgabe umfasst. Gibt sie eine vollständige Fehlzugriffszeit an, ziehe die Trefferprüfung ab, bevor du den Wert als zusätzliche Fehlzugriffsverzögerung behandelst. Würdest du die Suche doppelt berechnen, überschätztest du die AMAT.

Wichtige Erkenntnisse

  • Die AMAT addiert zur Trefferprüfung die erwarteten zusätzlichen Kosten von Fehlzugriffen.
  • Verwende dezimale Fehlzugriffsanteile und eine einheitliche Zeiteinheit.
  • Gewichte die Raten für Befehle und Daten nach der jeweiligen Anzahl der Zugriffe.
  • Eine niedrigere Fehlzugriffsrate kann gegenüber einer ausreichend langsameren Trefferzeit unterliegen.

4.2 Berechne aus Fehlzugriffen die Ausführungszeit

Die AMAT misst die Zeit pro Speicherzugriff. Der CPI-Wert misst Taktzyklen pro ausgeführtem Befehl. Um beides zu verbinden, zähle, wie viele Befehls- und Datenanforderungen jeder Befehl erzeugt und wie viele Wartezyklen diese Anforderungen hinzufügen.

Die Warteterme addieren

Bei einem einfachen Prozessor mit Ausführung in Befehlsreihenfolge, dessen Cache-Treffer im Basis-CPI-Wert enthalten sind, fügt ein nicht überlappter Fehlzugriff seine zusätzliche Verzögerung hinzu. Mit der Befehlsfehlzugriffsrate mI, den Datenzugriffen pro Befehl fD, der Datenfehlzugriffsrate mD und der Verzögerung P in Taktzyklen gilt:

Warte-CPI=mIP+fDmDP, CPU-Zeit=Befehlsanzahl×(Basis-CPI+Warte-CPI)×Taktperiode.

In diesem Modell erzeugt jeder Befehl eine Anforderung zum Holen des Befehls. Nur Lade- und Speicherbefehle erzeugen Datenanforderungen, daher multipliziere ihre Fehlzugriffsrate mit ihrer Häufigkeit. Unterscheiden sich ihre Verzögerungen, verwende in jedem Term eine eigene Verzögerung.

Von Anforderungen zu Wartezyklen rechnen

Der Basis-CPI-Wert sei 1,0, die Befehlsfehlzugriffsrate 2 %, die Häufigkeit von Lade- und Speicherbefehlen 30 %, die Datenfehlzugriffsrate 4 % und die Fehlzugriffsverzögerung 100 Taktzyklen. Die Befehlswartezyklen betragen 0,02×100=2,0 Taktzyklen pro Befehl. Die Datenwartezyklen betragen 0,3×0,04×100=1,2. Der gesamte CPI-Wert ist 4,2.

Mit einem perfekten Cache würde der CPI-Wert wieder auf 1,0 sinken. Bei gleichem Takt und gleicher Befehlsanzahl wäre das ein 4,2-facher Speedup. Die Datenfehlzugriffsrate ist doppelt so hoch wie die Befehlsfehlzugriffsrate, dennoch kosten Befehlsfehlzugriffe insgesamt mehr Zeit, weil jeder Befehl geholt wird und nur 30 % auf Daten zugreifen.

Setze die AMAT nicht direkt als CPI-Wert ein. Die AMAT gilt pro Zugriff und enthält die Bedienzeit bei Treffern. Die CPI-Berechnung addiert hier nur Wartezyklen über die bereits gezählte Basisausführung hinaus.

Ein schnellerer Takt erhöht die Kosten jedes Speicherwartens in Taktzyklen

Die DRAM-Latenz in Nanosekunden sinkt nicht, wenn der Prozessortakt steigt. Eine Verdopplung des Takts macht aus derselben Speicherwartezeit von 100 Taktzyklen beim neuen Takt 200 Taktzyklen. Der CPI-Wert des Beispiels wird zu

1+0,02×200+0,3×0,04×200=7,4.

Jeder neue Taktzyklus ist halb so lang, sodass sich die relative Ausführungszeit von 4,2 alten Taktzyklen pro Befehl auf umgerechnet 3,7 alte Taktzyklen ändert. Der Speedup beträgt 4,2/3,7≈1,14 und liegt damit weit unter zwei.

Verbesserungen verschieben den Engpass

Sinkt der Basis-CPI-Wert von 1,0 auf 0,5, während die Speicherwartezyklen bei 3,2 bleiben, wird der gesamte CPI-Wert zu 3,7. Wartezyklen beanspruchen nun 3,2/3,7≈86% der Taktzyklen. Eine Verbesserung des Kerns macht die unveränderte Speicherverzögerung zu einem größeren Anteil der Laufzeit, ein Beispiel für das amdahlsche Gesetz.

Das einfache Modell zählt alle Fehlzugriffsverzögerungen als Wartezyklen. Ausführung außerhalb der Befehlsreihenfolge und nichtblockierende Caches können Fehlzugriffe mit nützlicher Arbeit oder anderen Fehlzugriffen überlappen. Um diese Überlappung auf einem realen Rechner zu beurteilen, benötigt man Hardwarezähler und Laufzeitmessungen. Halte beim Vergleich von Entwürfen mit diesem Modell den Befehlsstrom gleich und gib an, welche Verzögerungen bereits im Basis-CPI-Wert enthalten sind.

Wichtige Erkenntnisse

  • Zähle Befehlsfehlzugriffe für jeden Befehl und Datenfehlzugriffe nur für Datenzugriffe.
  • Addiere zusätzliche Fehlzugriffswartezyklen zu einem Basis-CPI-Wert, der Treffer bereits enthält.
  • Rechne die Speicherzeit erneut in Taktzyklen um, wenn sich die Taktfrequenz ändert.
  • Vergleiche die Laufzeit anhand von CPI-Wert mal Taktperiode, nicht allein anhand des CPI-Werts.
  • Überlappung kann die tatsächlichen Wartezyklen gegenüber der einfachen Summe der Fehlzugriffsverzögerungen verringern.

4.3 Verschachtele die Kosten mehrerer Cacheebenen

Ein unterer Cache verringert die Verzögerung bei einem L1-Fehlzugriff. Er hat eine eigene Suchzeit und Fehlzugriffsrate, daher müssen die erwarteten Kosten der Hierarchie den Anteil der Anforderungen berücksichtigen, der jede Ebene erreicht.

Den Nenner der Rate beachten

Die lokale Fehlzugriffsrate einer Ebene ist die Anzahl ihrer Fehlzugriffe geteilt durch die Anzahl der Anforderungen an diese Ebene. Ihre globale Fehlzugriffsrate ist die Anzahl ihrer Fehlzugriffe geteilt durch alle Speicheranforderungen des Prozessors.

Schlagen 4 % der Zugriffe in L1 und davon 25 % in L2 fehl, erreichen nur 0,04×0,25=0,01 oder 1 % der ursprünglichen Anforderungen den Hauptspeicher. Eine lokale L2-Fehlzugriffsrate von 25 % sagt für sich allein nichts über den Anteil aller Anforderungen aus, die den Hauptspeicher erreichen: L1 hat den Strom zuerst gefiltert.

Für zwei nacheinander geprüfte Ebenen gilt:

AMAT=H1+m1(H2+m2P).

Dabei sind H1 und H2 Suchzeiten, m1 und m2 lokale Fehlzugriffsanteile und P die zusätzliche Hauptspeicherverzögerung. Nur bei L1-Fehlzugriffen fällt die L2-Suche an. Nur bei Fehlzugriffen in beiden Ebenen fällt die Hauptspeicherverzögerung an.

Von innen nach außen auswerten

Verwende eine L1-Trefferzeit von 1 Taktzyklus, eine L1-Fehlzugriffsrate von 4 %, eine L2-Trefferzeit von 12 Taktzyklen, eine lokale L2-Fehlzugriffsrate von 25 % und eine Hauptspeicherverzögerung von 200 Taktzyklen. Eine Anforderung, die L2 erreicht, benötigt im Mittel 12+0,25×200=62 zusätzliche Taktzyklen. Somit gilt

AMAT=1+0,04×62=3,48 Taktzyklen.

Ohne L2 betrüge die AMAT 1+0,04×200=9 Taktzyklen. Die L2-Suche erzeugt bei jedem L1-Fehlzugriff zusätzliche Arbeit, verhindert aber bei den meisten dieser Anforderungen die viel größere Hauptspeicherverzögerung.

Setze die globale L2-Fehlzugriffsrate von 1 % innerhalb der Klammern nicht für m2 ein. Das würde den L1-Fehlzugriffsanteil zweimal multiplizieren. Eine gleichwertige ausmultiplizierte Form verwendet die globale Rate direkt:

AMAT=H1+m1H2+(m1m2)P.
L3 nach derselben Logik hinzufügen

Bei einer L3-Trefferzeit von 40 Taktzyklen und einer lokalen Fehlzugriffsrate von 40 % beträgt der L3-Bedienterm 40+0,4×200=120 Taktzyklen. Der L2-Term wird zu 12+0,25×120=42 Taktzyklen. Die gesamte AMAT beträgt 1+0,04×42=2,68 Taktzyklen.

Der vollständige Ausdruck lautet H1+m1(H2+m2(H3+m3P)). L3 wird nur bei Anforderungen berechnet, die in beiden oberen Ebenen fehlschlagen. Eine Ebene mit einer sehr langsamen Suche oder sehr wenigen Treffern kann mehr Verzögerung hinzufügen, als sie einspart.

Für den CPI-Wert Raten pro Befehl verwenden

Angenommen, der Basis-CPI-Wert ist 1, L1 erzeugt 0,032 Fehlzugriffe pro Befehl und der Hauptspeicher fügt 100 Taktzyklen hinzu. Ohne L2 beträgt der CPI-Wert 1+0,032×100=4,2. Füge einen L2-Cache mit einer Trefferzeit von 10 Taktzyklen und einer lokalen Fehlzugriffsrate von 25 % hinzu:

CPI=1+0,032×10+0,032×0,25×100=2,12.

Bei gleichem Takt beträgt der Speedup 4,2/2,12≈1,98. Der Wert 0,032 gibt bereits Fehlzugriffe pro Befehl an; ein weiterer Faktor für die Zugriffshäufigkeit würde diese Häufigkeit also doppelt zählen.

Wichtige Erkenntnisse

  • Lokale und globale Fehlzugriffsraten haben unterschiedliche Nenner.
  • Multipliziere lokale Fehlzugriffsanteile, um den Anteil zu finden, der eine untere Ebene erreicht.
  • Werte verschachtelte Bedienzeiten von der untersten Ebene aufwärts aus.
  • Berechne die Suchzeit einer unteren Ebene nur für Anforderungen, die diese Ebene erreichen.
  • Verwende Fehlzugriffe pro Befehl bei der Berechnung des Warte-CPI-Werts direkt.
  • Ein zusätzlicher Cache hilft nur, wenn die vermiedene Verzögerung seine zusätzliche Sucharbeit übersteigt.
5

Erkläre, wie virtueller Speicher und TLBs in die Speicherhierarchie eingebunden sind

Programme geben virtuelle Adressen aus, während Caches letztlich physische Daten identifizieren. Seitentabellen liefern die Abbildung und Zugriffsrechte, und ein TLB hält kürzlich verwendete Übersetzungen nahe am Prozessor. Rechne eine Adressübersetzung durch, unterscheide eine fehlende Übersetzung von einem Seitenfehler und erfahre, wie sich Cacheindizierung und Übersetzung überlappen können. Hier gelten dieselben Hierarchieprinzipien, aber Übersetzungseinträge, Datenblöcke und Seiten haben unterschiedliche Aufgaben.

5.1 Übersetze Seiten und prüfe Berechtigungen

Virtueller Speicher trennt die von einem Programm verwendeten Adressen von den Plätzen, an denen seine Daten im Hauptspeicher liegen. Jeder Prozess erhält seinen eigenen virtuellen Adressraum. Die Hardware übersetzt Adressen anhand von Abbildungen des Betriebssystems und prüft, ob jeder angeforderte Zugriff erlaubt ist.

Die Seitennummer ersetzen, den Offset erhalten

Eine Seite ist ein Bereich virtueller Adressen mit fester Größe. Ein Seitenrahmen ist ein seitengroßer Platz im physischen Speicher. Bei 4-KiB-Seiten enthält jede Seite 4096 Byte, sodass der Seitenoffset 12 Bit benötigt. Die verbleibenden hohen Bits der virtuellen Adresse bilden die virtuelle Seitennummer oder VPN.

Ein Seitentabelleneintrag oder PTE bildet eine VPN auf eine physische Seitennummer oder PPN ab. Die Übersetzung ersetzt die Seitennummer, erhält aber den Offset: Im physischen Seitenrahmen wird dieselbe Byteposition ausgewählt.

Für die virtuelle Adresse 0x00403A7C ergeben die niederwertigen 12 Bits den Offset 0xA7C, und die VPN ist 0x00403. Wird diese VPN auf die PPN 0x02F1C abgebildet, lautet die physische Adresse 0x02F1CA7C. Das Anhängen eines 12-Bit-Offsets entspricht der Multiplikation der PPN mit 4096 und der Addition des Offsets; die Addition der unverschobenen PPN würde die falsche Adresse ergeben.

Eine Abbildung umfasst Berechtigungen

Ein PTE hält die Gültigkeit, eine physische Seitennummer und Berechtigungen wie Lesen, Schreiben, Ausführen und Benutzerzugriff fest. Zugriffs- und Änderungsbits halten Nutzung und Veränderung fest. Ein privilegiertes Prozessorregister bezeichnet die Seitentabelle; RISC-V verwendet satp. Benutzerprogramme können diese Abbildungen nicht beliebig umschreiben.

Getrennte Seitentabellen ermöglichen es, dass dieselbe virtuelle Adresse in verschiedenen Prozessen unterschiedliche physische Daten bezeichnet. Sie erlauben auch eine gezielte gemeinsame Nutzung: Zwei Prozesse können virtuelle Seiten auf denselben physischen Seitenrahmen abbilden, etwa um schreibgeschützten Bibliothekscode zu teilen. Sowohl Isolation als auch gemeinsame Nutzung ergeben sich aus kontrollierten Abbildungen.

Ein Seitenfehler erfordert die Behandlung durch das Betriebssystem

Ein Seitenfehler ist eine Ausnahme, die ausgelöst wird, wenn die Übersetzung oder ihre Berechtigungsprüfungen nicht normal abgeschlossen werden können. Ein Speicherbefehl auf eine schreibgeschützte Abbildung kann einen Seitenfehler auslösen, selbst wenn die Seite bereits im Hauptspeicher liegt.

Fehlt eine benötigte Seite im Hauptspeicher, beschafft das Betriebssystem einen physischen Seitenrahmen, liest die Seite aus dem Massenspeicher, aktualisiert die Abbildung und startet den Befehl erneut. Eine veränderte zu verdrängende Seite muss möglicherweise zuerst zurückgeschrieben werden. Manche Seitenfehler werden ohne Massenspeicher aufgelöst, etwa durch das Einrichten einer Abbildung auf eine vorhandene Seite oder die Behandlung von Copy-on-Write. Ein Zugriff, den das System nicht erlauben kann, kann stattdessen mit einem Prozessfehler enden.

Seitenfehler mit Massenspeicherzugriff sind teuer. Bei 3 GHz kostet eine Verzögerung von 50 µs 150.000 Taktzyklen und 1 ms kostet 3.000.000. Große Seiten verteilen Übertragungskosten auf viele Bytes. Eine virtuelle Seite kann jeden geeigneten Seitenrahmen belegen, und veränderte Seiten nutzen das Rückschreibverfahren, weil die Weiterleitung jedes Speicherbefehls an den Massenspeicher zu langsam wäre.

Auch Seitentabellen verbrauchen Speicher

Eine flache Tabelle für virtuelle 32-Bit-Adressen und 4-KiB-Seiten benötigt 232−12=220 Einträge. Bei 4 Byte pro Eintrag sind das 4 MiB pro Prozess. Reale Entwürfe verwenden mehrstufige Tabellen, um bei dünn belegten Adressräumen nicht eine riesige flache Tabelle anlegen zu müssen; RISC-V Sv39 verwendet drei Ebenen.

Virtueller Speicher umfasst Adressübersetzung, Schutz und gemeinsame Nutzung, selbst wenn jede verwendete Seite in den DRAM passt. Das Auslagern auf den Massenspeicher ist eine Anwendung dieses Mechanismus, nicht sein gesamter Zweck.

Wichtige Erkenntnisse

  • Die Übersetzung verändert die Seitennummer und erhält den Seitenoffset.
  • PTE-Berechtigungen steuern Lese- und Schreibzugriffe, Ausführung und Benutzerzugriff.
  • Ein Seitenfehler kann eine fehlende Seite oder ein Berechtigungsproblem bedeuten.
  • Manche Seitenfehler werden aufgelöst, ohne aus dem Massenspeicher zu lesen.
  • Seitentabellen unterstützen die Isolation von Prozessen und gezielte gemeinsame Nutzung.
  • Eine flache Tabelle hat einen Eintrag pro virtueller Seite, sodass ihr Speicherbedarf groß sein kann.

5.2 Speichere Übersetzungen in einem TLB zwischen

Die Adressübersetzung kann mehrere Seitentabellen-Lesezugriffe erfordern, bevor ein Datenzugriff fortgesetzt wird. Seitentabelleneinträge können in gewöhnlichen Caches treffen, aber diese Lesezugriffe erzeugen dennoch zusätzliche Arbeit. Der Translation Lookaside Buffer oder TLB speichert kürzlich verwendete Übersetzungen zwischen, sodass die meisten Zugriffe einen Seitentabellendurchlauf vermeiden können.

Einen erlaubten Zugriff verfolgen

Die virtuelle Seitennummer wird im TLB gesucht. Ein passender Eintrag liefert die physische Seitennummer und Berechtigungsinformationen. Nach den Berechtigungsprüfungen bezeichnet die physische Adresse die Daten in der Cachehierarchie.

Bei einem TLB-Fehlzugriff beschafft ein Seitentabellendurchlauf die Übersetzung. Ist die Abbildung gültig und erlaubt die Anforderung, wird die Übersetzung in den TLB eingetragen und der Zugriff fortgesetzt. RISC-V und x86-64 verwenden normalerweise Hardwareeinheiten für den Durchlauf; manche Architekturen verwenden Softwareroutinen. Kann die Abbildung die Anforderung nicht bedienen, löst der Prozessor einen Seitenfehler für das Betriebssystem aus.

Ein TLB-Fehlzugriff kann daher mit einem Datencache-Treffer oder einem Datencache-Fehlzugriff einhergehen. Er besagt, dass die Übersetzung im TLB fehlte, nicht, dass die Seite im DRAM fehlte. Umgekehrt kann ein TLB-Treffer mit einem Cache-Fehlzugriff oder einem Berechtigungsfehler bei einem verbotenen Zugriff einhergehen. Übersetzung und Vorhandensein von Daten beantworten unterschiedliche Fragen.

Den durch Übersetzungen abgedeckten Speicher zählen

Die TLB-Reichweite ist die Anzahl der Einträge multipliziert mit der Seitengröße. Ein TLB mit 64 Einträgen und 4-KiB-Seiten deckt gleichzeitig 256 KiB ab. Bei 2-MiB-Seiten decken 64 Einträge 128 MiB ab. Zugriffe auf viele verschiedene Seiten können die Übersetzungskapazität erschöpfen, selbst wenn nur wenige Bytes jeder Seite genutzt werden.

TLBs der ersten Ebene enthalten oft einige zehn Einträge; untere TLB-Ebenen können einige hundert oder tausend enthalten. Ihre Einträge umfassen Seitennummern-Tags, physische Abbildungen, Berechtigungen und häufig Adressraumkennungen. Lokalität innerhalb von Seiten und Wiederverwendung bei benachbarten Zugriffen halten die Trefferraten der Übersetzung hoch.

Benötigen beispielsweise 1 % der Zugriffe einen Seitentabellendurchlauf von 30 Taktzyklen und wird die TLB-Trefferzeit ansonsten verborgen, fügen die Durchläufe im Mittel 0,01×30=0,3 Taktzyklen pro Zugriff hinzu. Dieses Beispiel setzt voraus, dass die Durchläufe normal abgeschlossen werden, und schließt die Behandlung von Seitenfehlern aus.

Indizierung und Übersetzung überlappen

Ein physisch indizierter und physisch getaggter Cache wartet auf eine physische Adresse, bevor er seinen Satz auswählt. Ein virtuell indizierter und physisch getaggter Cache oder VIPT-Cache beginnt einen Satz zu lesen, während der TLB übersetzt, und vergleicht anschließend physische Tags.

Der einfache VIPT-Entwurf entnimmt alle Index- und Blockoffset-Bits dem Seitenoffset, weil die Übersetzung diese Bits erhält. Dies erfordert

Cachekapazita¨tWege≤Seitengro¨ße.

Bei 4-KiB-Seiten hat ein 8-fach assoziativer Cache mit 32 KiB 4 KiB pro Weg und erfüllt die Bedingung. Auch ein 12-fach assoziativer Cache mit 48 KiB erfüllt sie. Ein 8-fach assoziativer Cache mit 64 KiB hat 8 KiB pro Weg und benötigt ein Seitennummernbit für die Indizierung, braucht also mehr Wege oder eine zusätzliche Behandlung.

Zwischengespeicherte Abbildungen aktuell halten

Übersetzungen gehören zu Adressräumen. Ein Kontextwechsel kann alte Einträge löschen oder sie durch Adressraumkennungen oder ASIDs unterscheiden. Änderungen an Abbildungen erfordern die entsprechende Pflege des Übersetzungscaches; RISC-V stellt sfence.vma bereit. Wird eine Seite aus dem Hauptspeicher verdrängt, darf ihre alte Übersetzung im TLB nicht nutzbar bleiben. Der TLB enthält Abbildungen und Zugriffsrechte, während gewöhnliche Caches die Daten und Befehle des Programms enthalten.

Wichtige Erkenntnisse

  • Ein TLB speichert Übersetzungen und Berechtigungen, keine Programmdaten.
  • Ein erfolgreicher Seitentabellendurchlauf behebt einen TLB-Fehlzugriff ohne Seitenfehler.
  • Die TLB-Reichweite ist die Anzahl der Einträge mal Seitengröße.
  • Bei einfacher VIPT-Indizierung passen Index- und Blockoffset-Bits in den Seitenoffset.
  • ASIDs und die Invalidierung von Adressübersetzungen verhindern die Verwendung von Abbildungen aus dem falschen Adressraum oder einer alten Abbildung.
6

Schreibe Programme unter Berücksichtigung des Cacheverhaltens

Schleifen und Datenlayouts bestimmen, welche Bytes ein Prozessor als Nächstes anfordert. Verfolge diese Adressen, um räumliche Lokalität zu verbessern, nützliche Daten durch Kachelung zu erhalten und zu verstehen, wann Prefetching eine Wartezeit verbergen kann. Vergleiche zeilen- und spaltenweises Durchlaufen, Layouts für Datensätze und den Speicherbedarf von Kacheln, bevor du eine Änderung misst. Kapazität, Satzkonflikte, Übersetzungsreichweite und Speicherbandbreite helfen zu erklären, warum eine Transformation bei einer Arbeitslast funktioniert und bei einer anderen weniger hilft.

6.1 Wähle Schleifen und Layouts, die jede Cachezeile nutzen

Code, der das Cacheverhalten berücksichtigt, nutzt geholte Bytes, bevor ihr Block verdrängt wird. Beginne mit den Adressen, die die innere Schleife erzeugt. Frage dann, welche Daten wiederverwendet werden, wie weit die Zugriffe auseinanderliegen und ob diese Blöcke gemeinsam im Cache liegen können.

Arrays in Speicherreihenfolge durchlaufen

C und C++ speichern rechteckige Arrays zeilenweise. Benachbarte Spalten einer Zeile liegen im Speicher nebeneinander. Fortran, MATLAB und Julia speichern spaltenweise; NumPy-Arrays werden standardmäßig zeilenweise gespeichert. Der effiziente innere Durchlauf folgt dem tatsächlichen Layout.

Ein C-Array double a[1024][1024] belegt 8 MiB. Jede Zeile benötigt 8.192 Byte. Bei 64 Byte großen Cachezeilen enthält jede Cachezeile acht Double-Werte. Ein zeilenweiser Durchlauf kann alle acht nutzen, bevor er weitergeht; in einem einfachen Modell mit Laden auf Anforderung ergibt das etwa einen Kaltstart-Fehlzugriff pro acht Zugriffe.

Ein spaltenweiser Durchlauf legt zwischen aufeinanderfolgenden Zugriffen 8.192 Byte zurück. Er berührt 1.024 verschiedene Cachezeilen, bevor er in der nächsten Spalte erneut auf benachbarte Daten zugreift. Diese Cachezeilen belegen 64 KiB und überschreiten damit einen L1-Cache mit 32 KiB. Sie stehen auch in Konflikt: In einem Cache mit 64 Sätzen erhält eine Schrittweite von 128 Cachezeilen denselben Satzindex. Ein 8-fach assoziativer Satz kann keine 1.024 konkurrierenden Cachezeilen halten.

Padding einer Zeile auf 1.032 Double-Werte ergibt eine Schrittweite von 8.256 Byte oder 129 Cachezeilen. Aufeinanderfolgende Zeilen rücken dann modulo 64 jeweils um einen Satz weiter und verteilen so die Anforderungen. Padding behebt Abbildungskonflikte; die Datenmenge ist weiterhin relevant.

Schleifen vertauschen, wenn das Ergebnis erhalten bleibt

Die Schleifenvertauschung ändert, welche Schleife innerhalb einer anderen läuft. Bei zeilenweise gespeicherter Matrixmultiplikation durchläuft die Reihenfolge i, j, k eine Zeile von A, aber eine Spalte von B. In einem Modell für große Datenströme mit geringer Wiederverwendung zwischen Durchläufen kostet das etwa 1/8+1=1,125 Fehlzugriffe pro innerer Iteration.

Bei i, k, j durchläuft die innere Schleife Zeilen von B und C, während ein Element von A wiederverwendet wird. Zählt man für beide Zeilen jeweils einen neu geladenen Datenstrom, ergibt das etwa 1/8+1/8=0,25 Fehlzugriffe pro Iteration, 4,5-mal weniger. Bleibt die wiederholt aktualisierte Zeile von C im Cache, nähert sich die Anzahl 0,125. Cachekapazität und Konflikte entscheiden, welche Wiederverwendung erhalten bleibt.

Die Vertauschung muss das erforderliche Berechnungsverhalten erhalten. Abhängigkeiten, überlappende Zeiger und die Auswertungsreihenfolge von Gleitkommaoperationen können Transformationen einschränken; Compiler benötigen einen Nachweis, dass eine Änderung erlaubt ist.

Die verwendeten Felder holen

Ein Array von Strukturen gruppiert alle Felder eines Objekts. Eine Struktur von Arrays gruppiert ein Feld über mehrere Objekte hinweg. Enthält ein Teilchendatensatz acht Double-Werte in einer 64 Byte großen Cachezeile, werden beim Summieren allein von x über eine Million ausgerichtete Datensätze etwa 64 MB geladen. Ein separates zusammenhängendes x-Array lädt etwa 8 MB und nutzt jeden geholten Double-Wert. Für Code, der alle Teilchenfelder gemeinsam nutzt, kann das ursprüngliche Strukturlayout günstiger sein.

Verkettete Knoten können verstreut liegen, und jede nächste Adresse kann von einem gerade geladenen Zeiger abhängen. Zusammenhängende Arrays oder Knotenpools können die Lokalität verbessern. Kompakte häufig genutzte Felder ermöglichen außerdem, dass mehr aktive Daten in jede Ebene passen.

Miss vor und nach einer Änderung die Laufzeit und relevante Hardwarezähler. Cache-Fehlzugriffe können eine langsame Schleife erklären, aber auch Berechnungen, Bandbreite oder Sprünge können der begrenzende Faktor sein. Halte Eingabe und Ergebnisse vergleichbar, damit ein Geschwindigkeitsunterschied die untersuchte Änderung widerspiegelt.

Wichtige Erkenntnisse

  • Stimme die innere Schleife auf die Speicherreihenfolge des Arrays ab.
  • Große Schrittweiten, die Zweierpotenzen sind, können Anforderungen auf einen Satz konzentrieren.
  • Padding verändert die Abbildung; kompakte Layouts verringern die Anzahl der geholten Bytes.
  • Schleifenvertauschung muss das erforderliche Berechnungsverhalten erhalten.
  • Wähle Arrays von Strukturen oder Strukturen von Arrays entsprechend den verwendeten Feldern.
  • Miss den Engpass und überprüfe die Ergebnisse, wenn du Code änderst.

6.2 Verwende Kacheln wieder und lade Daten voraus

Schleifenvertauschung verbessert die Zugriffsreihenfolge. Die Blockung, auch Kachelung genannt, geht weiter, indem sie einen kleinen Datenbereich aktiv hält, bis seine nützliche Wiederverwendung abgeschlossen ist. Prefetching zieht eine künftige Übertragung vor, sodass sich ihre Verzögerung mit nützlicher Arbeit überlappt.

Eine Gruppe von Kacheln im Cache halten

Bei der gekachelten Multiplikation quadratischer Matrizen tragen eine Kachel von A und eine Kachel von B zu einer Kachel von C bei. Eine Kachel mit der Seitenlänge b enthält b2 Elemente. Die wiederholte Arbeit an diesen kleinen Kacheln verwendet Daten erneut, bevor der nächste Bereich folgt.

Bei 8 Byte großen Double-Werten benötigen drei Kacheln 3b2×8=24b2 Byte. In einem Cache mit 32 KiB liegt die Kapazitätsschranke bei

24b2≤32768,b≤32768/24≈36,9.

Eine Seitenlänge von 32 benötigt 24.576 Byte oder 24 KiB und lässt etwas Platz für andere Daten. Wählt man 36 nur deshalb, weil die Rechnung es erlaubt, bleibt viel weniger Platz und es können Konflikte auftreten. Die Kapazität ist eine erste Schätzung; tatsächliche Kachelgrößen werden durch Messungen abgestimmt.

Ein gekachelter Durchlauf erhöht die äußere Schleife um die Kachelgröße. Die inneren Schranken stoppen beim kleineren Wert aus Kachelende und Matrixgröße. Ist beispielsweise eine Dimension 70 und haben Kacheln die Seitenlänge 32, hat die letzte Kachel entlang dieser Dimension nur sechs Elemente. Eine letzte Kachel voller Größe würde über das Array hinaus zugreifen.

Abschätzen, was Wiederverwendung spart

In einem vereinfachten Modell für große Matrizen mit 64 Byte großen Cachezeilen hat die naive Reihenfolge i, j, k etwa 1,125N3 Fehlzugriffe, wenn durchlaufene Zeilen beim nächsten Durchgang nicht mehr im Cache liegen. Eine gekachelte Variante kann dies auf etwa N3/(4b) verringern, vorausgesetzt, die drei bearbeiteten Kacheln bleiben im Cache und Konflikte werden vernachlässigt.

Für N=1024 und b=32 betragen diese Schätzungen etwa 1,2 Milliarden und 8,4 Millionen Fehlzugriffe, ein Faktor von 144. Beide Varianten führen weiterhin etwa 2N3 Gleitkommaoperationen aus. Die Einsparung liegt in wiederholten Datenübertragungen, nicht in der Anzahl der Rechenoperationen der Multiplikation. Das Modell beschreibt ideale Wiederverwendung; der gemessene Speedup hängt auch von Bandbreite, Ausführung und anderem Aufwand ab.

Früh genug vorausladen, um Latenz zu verbergen

Hardware-Prefetcher erkennen Datenströme wie sequenzielle Zugriffe oder Zugriffe mit konstanter Schrittweite. Sie fordern Cachezeilen an, bevor Zugriffe auf Anforderung sie benötigen. Software kann ebenfalls das Vorausladen anfordern, zum Beispiel mit __builtin_prefetch von GCC oder Clang.

Der Zeitpunkt ist entscheidend. Eine zu spät gestellte Anforderung lässt den anfordernden Zugriff warten. Eine zu früh gestellte Anforderung kann eine Cachezeile laden, die vor ihrer Verwendung wieder verdrängt wird. Eine ungenaue Anforderung verbraucht Bandbreite und Cacheplatz, ohne dem Programm zu helfen. Das Verfolgen von Zeigern lässt sich schwerer durch Prefetching unterstützen, weil die nächste Adresse oft erst bekannt wird, nachdem der aktuelle Knoten eingetroffen ist.

Rechtzeitiges Prefetching kann spätere Fehlzugriffe auf Anforderung in Treffer verwandeln, aber die Cachezeilen durchlaufen weiterhin die Hierarchie. Es verbirgt Latenz, statt die benötigten Nutzdaten eines sequenziellen Durchlaufs zu verringern. Kachelung hilft, wenn Werte wiederverwendet werden; ein einmaliger Durchlauf hat keine wiederholt verwendeten Daten, die gehalten werden müssten, und kann bereits durch die Speicherbandbreite begrenzt sein.

Wichtige Erkenntnisse

  • Kachelung hält wiederverwendete Kacheln aktiv, solange ihre Daten nützlich sind.
  • Schätze den Kachelspeicher für alle gleichzeitig benötigten Arrays.
  • Behandle unvollständige Randkacheln mit begrenzten Schleifenschranken.
  • Kachelung verringert Datenübertragungen und erhält den Rechenaufwand.
  • Prefetching benötigt nützliche Adressen und genügend Vorlauf; ungenaue Anforderungen verschwenden Bandbreite.

Speicherhierarchie und Caches: Beispiele

6 Interaktive Lektionen

1

Vom Durchlaufen eines Arrays zur Speicherhierarchie

13 Schritte
Verbinde die Lokalität eines Programms mit Speichertechnologien und den Kosten von Treffern und Fehlzugriffen.
  1. 1
    EinführungWarum einen kleinen Speicher in der Nähe halten?

    Ein Prozessor kann Arbeit viel schneller ausgeben, als ein großer Speicher jede Anforderung beantworten kann. Ein Cache hilft, wenn ein Programm zu kürzlich verwendeten Daten zurückkehrt oder benachbarte Adressen nutzt; diese Wiederverwendung heißt Lokalität. Verfolge das Durchlaufen eines Arrays, um zu sehen, wie viel das Laden einer einzelnen Cachezeile bedienen kann, und verbinde diese Wiederverwendung mit den Technologien und Ebenen, die die Daten bereitstellen: der Speicherhierarchie.

  2. 2
    ErklärungUnterscheide zwei Arten von Lokalität

    Zeitliche Lokalität verwendet ein Element bald erneut: Ein Schleifenkörper wird wiederholt ausgeführt und eine laufende Summe bei jeder Iteration aktualisiert. Räumliche Lokalität nutzt benachbarte Adressen: Ein sequenzieller Arraydurchlauf liest benachbarte Elemente.

    Eine Schleife kann im Befehlsstrom beide Arten aufweisen, selbst wenn jedes Arrayelement nur einmal gelesen wird. Bestimme, worauf zugegriffen wird, bevor du eine Art der Lokalität zuordnest.

  3. 3
    BeispielWie viel liefert eine Cachezeile?

    Ein an einer Blockgrenze ausgerichtetes Array enthält 1000 Ganzzahlen zu je 4 Byte. Cachezeilen enthalten 64 Byte. Jedes Laden liefert 64/4=16 aufeinanderfolgende Ganzzahlen. Nachdem der Zugriff auf die erste Ganzzahl fehlschlägt, können die nächsten 15 treffen. Die letzte Cachezeile muss nicht voll sein: Das 4000 Byte große Array benötigt ⌈4000/64⌉=63 Cachezeilen.

  4. 4
    HerausforderungSage einen kleineren Durchlauf voraus

    Ein ausgerichtetes Array enthält 320 Ganzzahlen zu je vier Byte. Wie viele Lesezugriffe auf das Array schlagen in einem zunächst leeren Cache mit Laden auf Anforderung und 64 Byte großen Cachezeilen fehl, wenn es keine störenden Zugriffe gibt und das Array hineinpasst? Welche Lokalität ermöglicht die übrigen Treffer?

    ---reveal---

    Es gibt 16 Ganzzahlen pro Cachezeile und 320/16=20 Cachezeilen, sodass 20 Lesezugriffe fehlschlagen. Die anderen 300 treffen aufgrund räumlicher Lokalität. Jedes Element wird einmal verwendet; diese Treffer erfordern keine zeitliche Wiederverwendung der Elemente.

  5. 5
    KernaussageEine Arbeitsmenge braucht nutzbare Plätze

    Die Arbeitsmenge umfasst die während eines Zeitfensters verwendeten Blöcke. Eine kleine aktive Menge kann nahe am Prozessor bleiben, selbst wenn das ganze Programm groß ist.

    Sowohl Kapazität als auch Platzierung sind wichtig. Dürfen zwei aktive Blöcke nur einen gemeinsamen Eintrag nutzen, können sie sich gegenseitig verdrängen, während andere Einträge leer bleiben. In Registern gehaltene Schleifenvariablen benötigen auch keinen Datencacheplatz, selbst wenn der Quellcode sie wiederholt liest.

  6. 6
    ErklärungVergleiche stromversorgte Speicherzellen

    SRAM hält ein Bit in einer stabilen stromversorgten Schaltung und verwendet dafür typischerweise sechs Transistoren. Es benötigt keine Auffrischung und ist schnell, beansprucht aber viel Fläche pro Bit. DRAM hält Ladung auf einem Kondensator; durch den Ladungsverlust ist Auffrischung nötig. Seine dichteren Zellen machen es für großen Hauptspeicher geeignet.

    Beide sind flüchtig. „Statisch“ beschreibt, wie SRAM seinen Zustand unter Stromversorgung hält, nicht, ob es einen Stromausfall übersteht.

  7. 7
    BeispielErst warten, dann übertragen

    DRAM aktiviert eine Zeile im Zeilenpuffer einer Bank und bedient daraus ausgewählte Spalten. Bursts und überlappende Bankzugriffe erhöhen die Datenbereitstellungsrate. Sie beseitigen die anfängliche Zugriffsverzögerung nicht.

    Bei 60 ns anfänglicher Latenz benötigt eine mit 16 Byte/ns übertragene 64 Byte große Cachezeile weitere 4 ns. Die gesamte Bedienzeit beträgt etwa 64 ns. Der größte Teil dieser Wartezeit liegt vor der Übertragung, obwohl die Schnittstelle Bytes schnell überträgt.

  8. 8
    ErklärungWähle einen Speicher, der seinen Inhalt behält

    NAND-Flash behält Daten ohne Strom. Es liest und programmiert Seiten, während größere Blöcke gelöscht werden müssen, bevor programmierter Speicherplatz erneut verwendet werden kann. Diese Vorgänge dauern viel länger als ein SRAM- oder DRAM-Zugriff.

    Der Verschleiß durch Programmieren und Löschen begrenzt die Lebensdauer eines Blocks. Wear-Leveling verteilt Aktualisierungen über Blöcke, damit häufig geänderte logische Daten nicht einen physischen Platz vorzeitig verschleißen.

  9. 9
    HerausforderungUnterscheide dauerhafte Speicherung und Auffrischung

    Ein Gerät muss Aufzeichnungen behalten, nachdem die Stromversorgung abgeschaltet wurde. Würde das Ersetzen von DRAM durch SRAM diese Anforderung erfüllen? Erkläre.

    ---reveal---

    Nein. SRAM benötigt keine Auffrischung, verliert aber ohne Strom trotzdem seine Daten, genau wie DRAM. Nichtflüchtiger Speicher wie Flash erfüllt die Anforderung an die dauerhafte Speicherung. Seine langsameren Seitenoperationen und Löschanforderungen erklären, warum er eine andere Rolle als Cache-Speicher auf dem Chip erfüllt.

  10. 10
    ErklärungOrdne die Ebenen

    Register liegen der Ausführung am nächsten, gefolgt von L1, L2, L3, DRAM und Massenspeicher. Caches übertragen Blöcke, häufig 64 Byte groß, während virtueller Speicher Seiten verwendet, häufig 4 KiB groß.

    L1 trennt häufig Befehls- und Datencaches, damit die Pipeline gleichzeitig auf beide zugreifen kann. Bei einem Fehlzugriff in einer Ebene wird die Suche darunter fortgesetzt; ein L1-Fehlzugriff kann dennoch ein L2-Treffer sein.

  11. 11
    BeispielBerechne die Kosten gelegentlicher Fehlzugriffe

    Verwende eine vereinfachte Suche von 1 Taktzyklus, 97 % Treffer und eine zusätzliche Fehlzugriffsverzögerung von 100 Taktzyklen. Bei jeder Anforderung fällt die Suche an, und bei 3 % fällt die Verzögerung an:

    1+0,03×100=4 Taktzyklen.

    Ein Fehlzugriff kostet hier 101 Taktzyklen. Die 100 Taktzyklen sind zusätzliche Zeit; würde man sie als gesamte Fehlzugriffszeit berechnen, würde man die Suche bei Fehlzugriffen auslassen.

  12. 12
    HerausforderungVerbinde das Programm mit seinem Mittelwert

    Zwei Programme verwenden denselben Cache mit 1 Taktzyklus Trefferzeit und 80 Taktzyklen zusätzlicher Verzögerung. Eines hat 2 % Fehlzugriffe, das andere 20 %. Bestimme ihre mittleren Zeiten und erkläre, warum identische Hardware unterschiedliche Ergebnisse liefert.

    ---reveal---

    Die Mittelwerte sind 1+0,02×80=2,6 und 1+0,20×80=17 Taktzyklen. Unterschiedliche Zugriffsmuster erzeugen unterschiedliche Fehlzugriffsraten. Der Cache nutzt die Lokalität, die jedes Programm bietet; seine Kapazität und Technologie allein bestimmen das Ergebnis nicht.

  13. 13
    ZusammenfassungBetrachte einen Zugriff auf drei Ebenen

    Bestimme bei der Untersuchung des Speicherverhaltens das wiederverwendete Element, den mit ihm übertragenen Block und die Ebene, die es bereitstellt. Lokalität erklärt die wahrscheinliche Wiederverwendung, Speichertechnologie erklärt Kosten und Kapazität, und die Zeiten für Treffer und Fehlzugriffe machen aus diesen Beobachtungen eine Schätzung der Zugriffszeit. Beginne bei einem konkreten Programm mit dem tatsächlichen Adressstrom.

2

Baue eine Cachesuche auf und verfolge sie

15 Schritte
Zerlege Adressen, verfolge den Ersetzungszustand und vergleiche direkte Abbildung mit mehreren Wegen.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEine Adresse muss zwei Fragen beantworten
  2. 2
    ErklärungEntferne zuerst den Byteoffset
  3. 3
    ErklärungZähle Einträge vor Index-Bits
  4. 4
    HerausforderungPrüfe eine neue Feldaufteilung
  5. 5
    BeispielBerücksichtige das gespeicherte Tag
  6. 6
    BeispielBeginne mit einem leeren Cache
  7. 7
    BeispielBeobachte, wie ein Eintrag den Besitzer wechselt
  8. 8
    BeispielVervollständige die Ersetzungsfolge
  9. 9
    HerausforderungVerfolge Zugriffe, ohne Bytes und Blöcke zu verwechseln
  10. 10
    ErklärungMache aus Einträgen Sätze und Wege
  11. 11
    BeispielVerfolge die letzte Nutzung bei jedem Zugriff
  12. 12
    HerausforderungUnterscheide LRU von FIFO
  13. 13
    KernaussageErkenne den Nutzen zusätzlicher Wege
  14. 14
    HerausforderungVergleiche Entwürfe gleicher Kapazität
  15. 15
    ZusammenfassungFühre den Zustand durch die Suche fort
3

Diagnostiziere einen Fehlzugriff und erhalte veränderte Daten

12 Schritte
Klassifiziere Fehlzugriffe, verfolge veränderte zu verdrängende Blöcke und unterscheide Strategien für Schreibtreffer von denen für Schreibfehlzugriffe.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEin Fehlzugriff hat eine Ursache und einen Behandlungsablauf
  2. 2
    ErklärungBediene einen wartenden Lesezugriff
  3. 3
    ErklärungKlassifiziere mit dem richtigen Vergleich
  4. 4
    HerausforderungUnterscheide freie Kapazität von Konflikten
  5. 5
    VerbindungWähle, welche Kosten du verbessern willst
  6. 6
    ErklärungVerfolge einen Block beim Rückschreibverfahren
  7. 7
    ErklärungStelle Speicherbefehle beim Durchschreibverfahren in eine Warteschlange
  8. 8
    ErklärungLege eine eigene Regel für Schreibfehlzugriffe fest
  9. 9
    HerausforderungVerfolge einen Speicherbefehl und einen späteren Lesezugriff
  10. 10
    BeispielZähle den Datenverkehr in beiden Richtungen
  11. 11
    HerausforderungVerbinde die Klassifizierung mit dem Schreibverkehr
  12. 12
    ZusammenfassungHalte die Entscheidungen getrennt
4

Berechne die Kosten einer Hierarchie

16 Schritte
Gehe von einem Cache über gewichteten Datenverkehr zu CPI-Werten, Taktänderungen und mehreren Cacheebenen über.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungGib einen Nenner und eine Einheit an
  2. 2
    BeispielBerechne die AMAT für eine Ebene
  3. 3
    TippWandle nach der Berechnung um
  4. 4
    HerausforderungBerücksichtige eine angegebene vollständige Fehlzugriffszeit
  5. 5
    BeispielGewichte die tatsächlich auftretenden Anforderungen
  6. 6
    BeispielGehe von Zugriffen zu Befehlen über
  7. 7
    BeispielSchließe mit der Laufzeit ab
  8. 8
    HerausforderungErhöhe den Prozessortakt
  9. 9
    VerbindungPrüfe, ob Verzögerungen überlappen
  10. 10
    BeispielHalte lokale und globale Raten auseinander
  11. 11
    BeispielBerechne die Kosten der unteren Ebene
  12. 12
    BeispielKehre zum ursprünglichen Strom zurück
  13. 13
    HerausforderungErkenne einen Nennerfehler
  14. 14
    BeispielFüge eine weitere bedingte Ebene ein
  15. 15
    HerausforderungVerbinde Cacheverkehr mit dem CPI-Wert
  16. 16
    ZusammenfassungWähle die richtige Bezugsgröße
5

Übersetze eine Adresse, ohne Suchvorgänge zu verwechseln

15 Schritte
Verfolge Seitenoffsets, Berechtigungen, TLB-Seitentabellendurchläufe und die Indizierungsbeschränkung eines VIPT-Caches.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEine Adresse, zwei Suchprobleme
  2. 2
    BeispielFinde den unveränderten Teil
  3. 3
    BeispielVerwende den Seitentabelleneintrag
  4. 4
    HerausforderungÜbersetze ein anderes Byte
  5. 5
    ErklärungAuch eine gültige Seite hat Zugriffsrechte
  6. 6
    ErklärungBehandle eine fehlende Seite
  7. 7
    BeispielSchätze eine flache Tabelle ab
  8. 8
    ErklärungVerwende Übersetzungen im TLB erneut
  9. 9
    KernaussageVerfolge unabhängige Trefferergebnisse
  10. 10
    HerausforderungEntscheide, ob Massenspeicher benötigt wird
  11. 11
    BeispielBerechne die Übersetzungsreichweite
  12. 12
    ErklärungBeginne die Cacheindizierung während der Übersetzung
  13. 13
    HerausforderungPrüfe einen vorgeschlagenen L1-Entwurf
  14. 14
    VerbindungEntferne veraltete Übersetzungen
  15. 15
    ZusammenfassungHalte Übersetzungszustand und Datenzustand getrennt
6

Nutze jede geholte Cachezeile

13 Schritte
Analysiere Schrittweiten, wähle ein Datenlayout, bestimme die Größe wiederverwendbarer Kacheln und entscheide, was Prefetching verbergen kann.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungBeginne mit den Adressen der inneren Schleife
  2. 2
    BeispielNutze alle Double-Werte einer Cachezeile
  3. 3
    BeispielBetrachte Kapazität und Konflikte gemeinsam
  4. 4
    TippÄndere die Zeilenschrittweite
  5. 5
    HerausforderungWähle ein Layout für den Zugriff
  6. 6
    ErklärungVertausche Schleifen, um Datenströme zu nutzen
  7. 7
    ErklärungHalte drei Kacheln aktiv
  8. 8
    BeispielLass über die Kapazitätsschätzung hinaus Platz
  9. 9
    HerausforderungBegrenze Randkacheln an der Arrayschranke
  10. 10
    KernaussageUnterscheide weniger Übertragungen von weniger Rechenarbeit
  11. 11
    ErklärungLade voraus, während nützliche Arbeit weiterläuft
  12. 12
    HerausforderungErkläre einen kleineren Speedup als erwartet
  13. 13
    ZusammenfassungTeste eine konkrete Änderung

Speicherhierarchie und Caches: Übungsaufgaben

50 Übungsfragen in 5 Sets

Set 1: Speicherverhalten und Cachesuche10 Übungsfragen

Frage 1 von 10

Ein Programm liest jedes Element eines zusammenhängenden Arrays einmal in Adressreihenfolge. Welche Art von Lokalität erklärt, warum das Holen einer ganzen Cachezeile hilft?
  1. Zeitliche Lokalität innerhalb jedes Elements
  2. Räumliche Lokalität zwischen den Elementen
  3. Zeitliche Lokalität zwischen den Seiten
  4. Räumliche Lokalität bei wiederholten Werten
Antwort zeigenAntwort ausblenden
Antwort: B
Benachbarte Elemente liegen an benachbarten Adressen, sodass eine geholte Cachezeile mehrere bevorstehende Lesezugriffe bedient. Zeitliche Lokalität erfordert die Wiederverwendung eines Elements; werden die Elemente jeweils einmal gelesen, gibt es für sie keine zeitliche Wiederverwendung, auch wenn andere Programmteile wiederverwendet werden können.

Frage 2 von 10

Welche Eigenschaft macht bei DRAM eine Auffrischung nötig, bei SRAM aber nicht?
  1. DRAM sendet Daten an beiden Taktflanken.
  2. DRAM behält Daten ohne Stromversorgung.
  3. DRAM speichert jedes Bit in einem stabilen Latch.
  4. DRAM speichert Ladung, die allmählich entweicht.
Antwort zeigenAntwort ausblenden
Antwort: D
Eine DRAM-Zelle speichert Ladung auf einem Kondensator. Da Ladung entweicht, muss sie regelmäßig wiederhergestellt werden. Die Übertragung an beiden Taktflanken verbessert die Schnittstellenbandbreite, ist aber nicht der Grund für die Auffrischung. SRAM hält seinen Zustand in einer stromversorgten Schaltung ohne regelmäßige Auffrischung.

Frage 3 von 10

Eine Anforderung schlägt in L1 fehl und trifft in L2. Welche Aussage beschreibt diesen Zugriff?
  1. L2 liefert einen Block, der in L1 fehlt.
  2. DRAM liefert einen Block, der in L2 fehlt.
  3. Der Befehl löst einen Seitenfehler aus.
  4. Der TLB muss eine Übersetzung nachladen.
Antwort zeigenAntwort ausblenden
Antwort: A
Treffer und Fehlzugriff beschreiben die jeweils geprüften Ebenen: In L1 fehlte der Block, während L2 ihn enthielt. Ein L1-Fehlzugriff benötigt kein DRAM, wenn ein unterer Cache ihn bedienen kann. Aus den Cacheergebnissen geht nicht hervor, ob die Übersetzung fehlschlägt oder ein Seitenfehler aufgetreten ist.

Frage 4 von 10

Ein direkt abgebildeter Cache hat 8 KiB Daten, 32 Byte große Blöcke und 30-Bit-Byteadressen. Wie breit sind Tag, Index und Offset?
  1. 17, 8, 5 Bit
  2. 12, 13, 5 Bit
  3. 18, 7, 5 Bit
  4. 17, 5, 8 Bit
Antwort zeigenAntwort ausblenden
Antwort: A
Der Cache hat 8192/32=256 Einträge und benötigt 8 Index-Bits. Ein 32 Byte großer Block benötigt 5 Offset-Bits, sodass 30−8−5=17 Tag-Bits verbleiben. Bei 13 Index-Bits würde man den Logarithmus der Kapazität in Byte bilden und den Blockoffset doppelt zählen.

Frage 5 von 10

Ein direkt abgebildeter Cache hat acht Einträge zu je 16 Byte. Welches Paar gibt für die Byteadresse 0x2B6 den Index des Eintrags und den Byteoffset an?
  1. Index 6, Offset 3
  2. Index 2, Offset 6
  3. Index 3, Offset 6
  4. Index 3, Offset 11
Antwort zeigenAntwort ausblenden
Antwort: C
Die Division von 0x2B6 durch 16 ergibt Block 0x2B oder 43 mit dem Rest 6. Block 43 modulo 8 wählt Index 3. Die niederwertigen drei Bits der unverschobenen Byteadresse würden Index 6 ergeben, weil diese Bits zum Byteoffset statt zum Blockindex gehören.

Frage 6 von 10

Ein leerer direkt abgebildeter Cache hat zwei Einträge zu je 8 Byte. Lesezugriffe verwenden in dieser Reihenfolge die Byteadressen 0x00, 0x07, 0x10, 0x04. Wie hoch ist die Trefferrate?
  1. 0%
  2. 25%
  3. 50%
  4. 75%
Antwort zeigenAntwort ausblenden
Antwort: B
Der erste Zugriff lädt Block 0, und 0x07 trifft in diesem Block. Die Adresse 0x10 lädt Block 2 in denselben Eintrag und verdrängt Block 0, sodass 0x04 anschließend fehlschlägt. Nur einer von vier Zugriffen trifft; wer den letzten Zugriff als Treffer zählt, übersieht die zwischenzeitliche Ersetzung.

Frage 7 von 10

Ein ausgerichtetes Array enthält 192 Werte zu je acht Byte. Ein zunächst leerer Cache verwendet 64 Byte große Cachezeilen, hat Platz für das gesamte Array und führt kein Prefetching aus. Wie viele Fehlzugriffe treten bei einem sequenziellen Durchlauf auf, wenn keine anderen Zugriffe stattfinden?
  1. 12
  2. 64
  3. 192
  4. 24
Antwort zeigenAntwort ausblenden
Antwort: D
Jede Cachezeile enthält 64/8=8 Werte, sodass der Durchlauf 192/8=24 Cachezeilen berührt. Der erste Lesezugriff auf jede Cachezeile schlägt fehl und die nächsten sieben Werte treffen. Wer 192 Fehlzugriffe zählt, behandelt das Laden einer Cachezeile so, als liefere es nur das einzelne angeforderte Element.

Frage 8 von 10

Eine Speicheranforderung hat eine anfängliche Latenz von 45 ns, gefolgt von einer Übertragung von 128 Byte mit 32 GB/s. Wie groß ist ihre gesamte Bedienzeit in diesem Modell?
  1. 49 ns
  2. 45 ns
  3. 77 ns
  4. 41 ns
Antwort zeigenAntwort ausblenden
Antwort: A
Bei 32 GB/s überträgt die Schnittstelle 32 Byte pro Nanosekunde, sodass 128 Byte 4 ns benötigen. Mit den anfänglichen 45 ns ergibt das 49 ns. Der Wert 77 ns verwechselt die Bandbreitenzahl mit einer Verzögerung, statt die Blockgröße durch die Übertragungsrate zu teilen.

Frage 9 von 10

Ein direkt abgebildeter Cache mit Rückschreibverfahren hat 4 KiB, 32 Byte große Cachezeilen und 24-Bit-Byteadressen. Zähle Daten, Tags, ein Gültigkeitsbit und ein Änderungsbit pro Cachezeile, ohne weitere Metadaten. Wie viele Bits werden gespeichert?
  1. 34.304 Bits
  2. 34.944 Bits
  3. 34.560 Bits
  4. 33.024 Bits
Antwort zeigenAntwort ausblenden
Antwort: C
Es gibt 128 Cachezeilen, daher sind Index und Offset 7 und 5 Bit breit und es verbleibt ein 12-Bit-Tag. Jede Cachezeile speichert 256 + 12 + 1 + 1 = 270 Bits, insgesamt also 34.560 Bits. Die Antwort mit 34.304 Bits lässt beide Steuerbits jeder Cachezeile aus, obwohl sie ausdrücklich mitgezählt werden sollen.

Frage 10 von 10

Ein leerer direkt abgebildeter Cache hat vier Einträge zu je 16 Byte. Lesezugriffe verwenden 0x24, 0x28, 0x64, 0x34, 0x2C, 0x68. Welche Trefferrate ergibt sich und welcher Block steht am Ende bei Index 2?
  1. 50 %; Block 2
  2. 25 %; Block 6
  3. 16,7 %; Block 2
  4. 16,7 %; Block 6
Antwort zeigenAntwort ausblenden
Antwort: D
Die Blockfolge lautet 2, 2, 6, 3, 2, 6. Nur der zweite Zugriff trifft; die Blöcke 2 und 6 ersetzen sich bei Index 2 gegenseitig, wo am Ende Block 6 steht. Die Antwort mit 50 % hält fälschlich beide konkurrierenden Blöcke im Cache und behandelt ihn so, als hätte er zusätzliche Platzierungsmöglichkeiten.
Set 2: Platzierung, Fehlzugriffe und Speicherbefehle10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Programm greift erstmals auf einen Block zu und der angeforderte Zugriff schlägt fehl. Wie wird dieser Fehlzugriff im Drei-C-Modell klassifiziert?
  1. Konfliktbedingt
  2. Kapazitätsbedingt
  3. Obligatorisch
  4. Kohärenzbedingt
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Cache mit Rückschreibverfahren verdrängt einen gültigen Block, dessen Änderungsbit nicht gesetzt ist. Was muss mit diesem Block geschehen?
  1. Er muss vor dem Ersetzen nach unten geschrieben werden.
  2. Er kann ohne Zurückschreiben verworfen werden.
  3. Sein Ersatz muss das Durchschreibverfahren nutzen.
  4. Sein Änderungsbit muss vor der Verdrängung gesetzt werden.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Ein Cache mit 12 KiB hat 64 Byte große Cachezeilen und drei Wege pro Satz. Wie viele Sätze hat er?
  1. 32
  2. 192
  3. 64
  4. 256
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein voller 2-fach assoziativer Satz verwendet LRU und enthält anfangs P und Q, wobei P am längsten nicht verwendet wurde. Die Zugriffe lauten Q, P, R, Q; R fehlt. Welche Blöcke werden bei den beiden Fehlzugriffen verdrängt?
  1. Q, dann P
  2. P, dann R
  3. P, dann Q
  4. Q, dann R
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Cache mit No-Write-Allocate-Verfahren ist anfangs leer. Auf einen Speicherbefehl für die Adresse 0x80 folgt ein Lesezugriff auf 0x80, ohne dazwischenliegende Zugriffe. Was geschieht in diesem Cache?
  1. Schreibzugriff schlägt fehl; Lesezugriff trifft.
  2. Schreibzugriff trifft; Lesezugriff trifft.
  3. Schreibzugriff trifft; Lesezugriff schlägt fehl.
  4. Schreibzugriff schlägt fehl; Lesezugriff schlägt fehl.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Ein wiederholter Zugriff auf Anforderung schlägt in einem direkt abgebildeten Cache fehl, trifft aber in einem vollassoziativen LRU-Cache gleicher Größe mit derselben Zugriffsfolge. Was verursacht nach dem Drei-C-Test den Fehlzugriff?
  1. Ein erster Zugriff auf den Block
  2. Eine Beschränkung der Blockplatzierung
  3. Eine zu geringe vollassoziative Kapazität
  4. Ein Schreibpufferüberlauf der unteren Ebene
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Cache mit Durchschreibverfahren hat einen endlichen Schreibpuffer. Speicherbefehle treffen über längere Zeit schneller ein, als die untere Ebene sie annehmen kann. Was geschieht schließlich?
  1. Der Cache wechselt zum Rückschreibverfahren.
  2. Die untere Ebene verwirft wartende Schreibzugriffe.
  3. Der Prozessor hält an, wenn der Puffer voll ist.
  4. Der Puffer beseitigt die Bandbreitenbeschränkung.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein leerer vollassoziativer LRU-Cache mit zwei Cachezeilen erhält die Blocklesezugriffe 1, 2, 3, 1, 2. Wie viele obligatorische, kapazitätsbedingte und konfliktbedingte Fehlzugriffe treten auf?
  1. 2 obligatorische, 3 kapazitätsbedingte, 0 konfliktbedingte
  2. 3 obligatorische, 0 kapazitätsbedingte, 2 konfliktbedingte
  3. 3 obligatorische, 1 kapazitätsbedingter, 1 konfliktbedingter
  4. 3 obligatorische, 2 kapazitätsbedingte, 0 konfliktbedingte
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Ein leerer Cache mit einer Cachezeile, Rückschreib- und Write-Allocate-Verfahren verwendet 32 Byte große Cachezeilen. Er erhält Speicherbefehle für 0x00, 0x04, 0x20 und 0x24, dann einen Lesezugriff auf 0x40. Wie viele Bytes werden zwischen diesem Cache und der nächsten Ebene übertragen, wenn nur Ladevorgänge und Rückschreibvorgänge verdrängter Blöcke zählen?
  1. 160 Byte
  2. 96 Byte
  3. 128 Byte
  4. 192 Byte
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Ein leerer 2-fach assoziativer Cache hat zwei Sätze und LRU-Ersetzung. Die Blocklesezugriffe 0, 2, 4 wiederholen sich unbegrenzt. Wie hoch ist die Trefferrate nach der Einlaufphase und was würde ein vollassoziativer Cache mit vier Cachezeilen tun?
  1. Zwei Drittel; er hätte ebenfalls ein Drittel Fehlzugriffe.
  2. Null; er würde nach seinen ersten drei Fehlzugriffen treffen.
  3. Ein Drittel; er würde nach vier Fehlzugriffen treffen.
  4. Null; er hätte ebenfalls bei jedem Zugriff einen Fehlzugriff.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 3: Zugriffszeit und Programmgeschwindigkeit10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Cache verzeichnet 184 Treffer bei 200 Zugriffen. Wie hoch ist seine Fehlzugriffsrate?
  1. 8%
  2. 16%
  3. 92%
  4. 0,08%
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Bericht gibt L2-Fehlzugriffe geteilt durch alle Anforderungen an, die L2 erreicht haben. Welche Rate wird angegeben?
  1. Globale L2-Fehlzugriffsrate
  2. Globale L1-Fehlzugriffsrate
  3. Lokale L2-Fehlzugriffsrate
  4. Lokale Speicherzugriffsrate
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Ein Cache hat eine Suchzeit von 2 Taktzyklen, 6 % Fehlzugriffe und eine zusätzliche Verzögerung von 75 Taktzyklen pro Fehlzugriff. Wie groß ist seine AMAT bei 2,5 GHz?
  1. 6,5 ns
  2. 1,8 ns
  3. 3,0 ns
  4. 2,6 ns
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Der Basis-CPI-Wert beträgt 1,2, die Befehlsfehlzugriffsrate 1 %, 40 % der Befehle führen einen Datenzugriff aus, die Datenfehlzugriffsrate beträgt 5 % und alle Fehlzugriffe fügen ohne Überlappung 80 Taktzyklen hinzu. Wie hoch ist der gesamte CPI-Wert?
  1. 6,0
  2. 3,6
  3. 2,8
  4. 2,4
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

L1 verzeichnet bei 8 % der Anforderungen einen Fehlzugriff. L2 hat eine lokale Fehlzugriffsrate von 15 %. Welcher Anteil der ursprünglichen Anforderungen schlägt in beiden Caches fehl?
  1. 1,2%
  2. 15%
  3. 23%
  4. 0,12%
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Cachesuche dauert 1 ns. Die Fehlzugriffsrate beträgt 10 % und ein vollständiger Fehlzugriff dauert einschließlich dieser Suche 41 ns. Wie groß ist die AMAT?
  1. 5,1 ns
  2. 4,1 ns
  3. 5,0 ns
  4. 4,0 ns
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Jeder Befehl erzeugt einen Befehlsabruf und im Mittel 0,5 Datenzugriffe. Die Fehlzugriffsraten für Befehle und Daten betragen 1 % und 7 %. Beide Caches haben eine Suchzeit von 2 Taktzyklen und eine zusätzliche Fehlzugriffsverzögerung von 60 Taktzyklen. Wie groß ist die AMAT pro Speicherzugriff?
  1. 4,7 Taktzyklen
  2. 3,8 Taktzyklen
  3. 4,4 Taktzyklen
  4. 2,7 Taktzyklen
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Die L1-Suche dauert 2 Taktzyklen und schlägt bei 5 % fehl. Die L2-Suche dauert 8 Taktzyklen und schlägt lokal bei 20 % fehl. Die L3-Suche dauert 30 Taktzyklen und schlägt lokal bei 10 % fehl. Der Hauptspeicher fügt nach einem L3-Fehlzugriff 150 Taktzyklen hinzu. Wie groß ist die AMAT?
  1. 2,45 Taktzyklen
  2. 4,35 Taktzyklen
  3. 3,95 Taktzyklen
  4. 2,85 Taktzyklen
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Ein Programm hat bei 2 GHz einen Basis-CPI-Wert von 1,5 und 2,5 nicht überlappte Speicherwartezyklen pro Befehl. Der Takt steigt auf 4 GHz; Befehlsanzahl, Basis-CPI-Wert, Fehlzugriffszahlen und Speicherverzögerungen in Nanosekunden bleiben gleich. Wie groß ist der Speedup?
  1. Etwa 1,23-fach
  2. Etwa 2,00-fach
  3. Etwa 0,62-fach
  4. Etwa 1,60-fach
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Cache A hat eine Suchzeit von 0,8 ns und 6 % Fehlzugriffe. Cache B hat eine Suchzeit von 1,1 ns und 4 % Fehlzugriffe. Beide verwenden dieselbe zusätzliche Fehlzugriffsverzögerung. Bei welcher Verzögerung sind ihre AMAT-Werte gleich?
  1. 5 ns
  2. 10 ns
  3. 15 ns
  4. 30 ns
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 4: Seiten, TLBs und Cacheindizierung10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Welcher Teil einer Adresse bleibt bei der üblichen Seitenübersetzung unverändert?
  1. Die virtuelle Seitennummer
  2. Die physische Seitennummer
  3. Die Basisadresse der Seitentabelle
  4. Der Byteoffset innerhalb der Seite
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Zugriff schlägt im TLB fehl und ein Seitentabellendurchlauf findet eine gültige Abbildung, die den Zugriff erlaubt. Was ist normalerweise der nächste Schritt?
  1. Die Seite aus dem Massenspeicher lesen.
  2. Die Übersetzung eintragen und fortfahren.
  3. Den Prozess wegen einer falschen Adresse beenden.
  4. Die Datencachezeile invalidieren.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Bei 8-KiB-Seiten wird die virtuelle Adresse 0x12345 auf die physische Seitennummer 0x2A abgebildet. Wie lautet die physische Byteadresse?
  1. 0x54345
  2. 0x2A345
  3. 0x54045
  4. 0x16345
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein vollassoziativer TLB enthält 96 Übersetzungen, alle für 16-KiB-Seiten. Wie groß ist seine Reichweite?
  1. 96 KiB
  2. 1.536 MiB
  3. 1,5 MiB
  4. 6 MiB
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Prozess schreibt auf eine im Hauptspeicher vorhandene Seite. Der TLB trifft, aber ihre aktuelle Abbildung gewährt nur Lesezugriff. Was geschieht?
  1. Der Schreibzugriff gelingt wegen des Übersetzungstreffers.
  2. Der TLB muss vor einem Fehler zunächst fehlschlagen.
  3. Die Seite muss erneut aus dem Massenspeicher geladen werden.
  4. Der Prozessor löst einen Seitenfehler wegen fehlender Berechtigung aus.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Ein einfacher VIPT-Cache verwendet 64 Byte große Cachezeilen und 4-KiB-Seiten. Seine Datenkapazität beträgt 64 KiB. Was ist die kleinste Assoziativität als Zweierpotenz, bei der alle Satzindex- und Blockoffset-Bits innerhalb des Seitenoffsets bleiben?
  1. 8-fach
  2. 16-fach
  3. 32-fach
  4. 4-fach
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Eine flache Seitentabelle deckt einen byteadressierten virtuellen 36-Bit-Adressraum mit 16-KiB-Seiten und 8 Byte großen Einträgen ab. Wie viel Speicher benötigt eine vollständige Tabelle?
  1. 4 MiB
  2. 16 MiB
  3. 32 MiB
  4. 64 MiB
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein leerer vollassoziativer LRU-TLB mit vier Einträgen verwendet 4-KiB-Seiten. Eine Schleife liest wiederholt je einen 8 Byte großen Wert an den Adressen 0x0000, 0x1000, 0x2000, 0x3000, 0x4000 in dieser Reihenfolge. Alle Seiten liegen im Hauptspeicher. Was geschieht nach der Einlaufphase?
  1. Jede Übersetzungssuche schlägt fehl; Seitenfehler sind nicht nötig.
  2. Nur die erste Suche jeder Schleife schlägt fehl; Seitenfehler sind nicht nötig.
  3. Jede Übersetzungssuche schlägt fehl; jede erfordert einen Massenspeicherzugriff.
  4. Alle Übersetzungssuchen treffen; es wird nur auf 40 Byte zugegriffen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Bei einem erlaubten Zugriff dauert ein Datencache-Treffer 2 Taktzyklen. Eine TLB-Suche kostet vor der Cachesuche immer 1 Taktzyklus. TLB-Fehlzugriffe treten bei 2 % der Zugriffe auf und fügen einen Seitentabellendurchlauf von 40 Taktzyklen hinzu; Datencache-Fehlzugriffe treten bei 5 % auf und fügen 80 Taktzyklen hinzu. Keine Kosten überlappen und es treten keine Seitenfehler auf. Wie groß ist die mittlere Zugriffszeit?
  1. 6,8 Taktzyklen
  2. 4,8 Taktzyklen
  3. 7,6 Taktzyklen
  4. 7,8 Taktzyklen
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Die Prozesse P und Q bilden unterschiedliche virtuelle Seiten auf den physischen Seitenrahmen 7 ab. P darf schreiben; Q darf nur lesen. P verändert ein Byte und das System koordiniert die Sichtbarkeit korrekt. Was folgt, wenn Q später dieses abgebildete Byte liest oder beschreibt?
  1. Q liest eine eigene getrennte Kopie und darf schreiben.
  2. Q kann die Änderung lesen, aber ein Schreibzugriff löst einen Fehler aus.
  3. Bei Q lösen beide Operationen einen Fehler aus, weil P geschrieben hat.
  4. Q liest die Änderung und erbt das Schreibrecht von P.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 5: Codeänderungen und Zielkonflikte der Hierarchie10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Welcher Durchlauf besucht benachbarte Elemente eines gewöhnlichen rechteckigen C-Arrays a[i][j]?
  1. Erhöhe i, während j fest bleibt.
  2. Verringere i, während j fest bleibt.
  3. Erhöhe j, während i fest bleibt.
  4. Erhöhe i und j gleichzeitig.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein ausgerichtetes Array hat 600 Datensätze zu je 48 Byte. Eine Schleife liest nur ein 8 Byte großes Feld pro Datensatz. Welches Layout minimiert bei einem Durchlauf durch einen zunächst leeren Cache mit 64 Byte großen Cachezeilen und ohne Prefetching die übertragenen Daten für dieses Feld?
  1. Ein separates zusammenhängendes Array für das Feld.
  2. Dieselben Datensätze in ihrer ursprünglichen Reihenfolge.
  3. Dieselben Datensätze in umgekehrter Reihenfolge.
  4. Dieselben Datensätze mit je 16 Padding-Bytes.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Drei quadratische Kacheln aus 8 Byte großen Werten müssen in einen Cache mit 48 KiB passen. Welche der angegebenen Kachelseitenlängen passt und lässt mindestens 8 KiB frei?
  1. 48
  2. 44
  3. 42
  4. 40
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Software-Prefetching verringert bei einem einmaligen Durchlauf die Cache-Fehlzugriffe auf Anforderung, aber die Laufzeit bleibt gleich. Die Speicherschnittstelle übertrug bereits an ihrer dauerhaft erreichbaren Grenze. Welche Erklärung passt?
  1. Nur Durchläufe, die jedes Element wiederverwenden, können Übertragungslatenz verbergen.
  2. Der Durchlauf benötigt weiterhin dieselben bandbreitenbegrenzten Übertragungen.
  3. Die niedrigere Fehlzugriffsrate auf Anforderung beweist, dass weniger Bytes übertragen werden.
  4. Vorausgeladene Daten können die Bandbreitengrenze der Schnittstelle umgehen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Cache hat 32 Sätze, 64 Byte große Cachezeilen und genügend Gesamtkapazität für die aktiven Daten. Ein spaltenweiser Durchlauf springt zwischen Zeilen aus je 256 Double-Werten; alle Zeilenanfänge sind an Cachezeilengrenzen ausgerichtet. Welches Padding verteilt aufeinanderfolgende Zeilenanfänge über alle Sätze?
  1. Ergänze auf 264 Double-Werte pro Zeile.
  2. Ergänze auf 272 Double-Werte pro Zeile.
  3. Ergänze auf 288 Double-Werte pro Zeile.
  4. Ergänze auf 320 Double-Werte pro Zeile.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Matrixdimension beträgt 94 und die Kachelseitenlänge 24. Jede Kachelkoordinate bezeichnet einen Bereich, einschließlich unvollständiger Randbereiche. Wie viele Kachelbereiche gibt es und wie viele Elemente enthält der Bereich unten rechts?
  1. 16 Bereiche; 576 Elemente
  2. 9 Bereiche; 484 Elemente
  3. 16 Bereiche; 484 Elemente
  4. 9 Bereiche; 576 Elemente
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein gekachelter Matrixkernel verwendet drei quadratische Kacheln aus Double-Werten in einem Cache mit 32 KiB. Ein Vorschlag ändert die Kachelseitenlänge von 16 auf 40 und sagt mit dem Modell im Cache bleibender Kacheln 2,5-mal weniger Fehlzugriffe voraus. Welche Beurteilung ist gerechtfertigt?
  1. Drei Kacheln benötigen 12,5 KiB; die vorhergesagte Verringerung ist gerechtfertigt.
  2. Drei Kacheln benötigen 37,5 KiB; die Annahme zum Verbleib im Cache gilt nicht.
  3. Drei Kacheln benötigen 37,5 KiB; die Fehlzugriffe müssen um den Faktor 6,25 sinken.
  4. Drei Kacheln benötigen 37,5 KiB; unveränderte Rechenarbeit bestimmt die Fehlzugriffe.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein festgelegtes Programm hat ohne L2 0,04 L1-Fehlzugriffe pro Befehl, einen Basis-CPI-Wert von 1 und eine Hauptspeicherverzögerung von 120 Taktzyklen. Ein vorgeschlagener L2-Cache fügt eine Suche von 12 Taktzyklen hinzu und hat lokal 10 % Fehlzugriffe; alle Wartezeiten fallen nacheinander an. Wie groß ist der Speedup bei gleichem Takt?
  1. Etwa 1,25-fach
  2. Etwa 3,92-fach
  3. Etwa 2,00-fach
  4. Etwa 2,96-fach
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine Matrixmultiplikation mit zeilenweise gespeicherten Matrizen wechselt von i-j-k zu i-k-j. Im Datenstrommodell hat die erste Reihenfolge 1,125 Fehlzugriffe pro innerer Iteration. In der neuen Reihenfolge wird B mit einem Fehlzugriff pro acht Iterationen durchlaufen und die Zeile von C bleibt nach der Einlaufphase im Cache. Welcher Faktor für die Verringerung der Fehlzugriffe im stationären Zustand ergibt sich, wenn anderer Datenverkehr vernachlässigt wird?
  1. 4,5-fach
  2. 8-fach
  3. 9-fach
  4. 0,25-fach
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Ein Cache enthält 128 Datenzeilen. Eine Schleife durchläuft wiederholt fünf Blöcke, die alle auf einen Satz abgebildet werden. Vergleiche einen 4-fach assoziativen LRU-Entwurf mit einem 8-fach assoziativen LRU-Entwurf gleicher Cachezeilengröße und Datenkapazität; die fünf Blöcke teilen sich in beiden einen Satz. Was ändert sich nach der Einlaufphase?
  1. Der 4-fache Cache schlägt jedes Mal fehl; der 8-fache trifft jedes Mal.
  2. Beide treffen jedes Mal, weil fünf kleiner als 128 ist.
  3. Der 4-fache Cache trifft einmal pro Zyklus; der 8-fache zweimal.
  4. Beide schlagen jedes Mal fehl, weil sie den Satzindex teilen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe

Schlüsselbegriffe

80 Schlüsselbegriffe, jeweils mit Definition

A

Amdahlsches Gesetz
Das amdahlsche Gesetz begrenzt den Gesamt-Speedup durch den Anteil der Ausführungszeit, den eine Verbesserung betrifft, und durch die unverändert bleibende Zeit.
Eine Verringerung der Ausführungskosten des Kerns lässt Speicherwartezeiten einen größeren Teil der Laufzeit ausmachen, wenn diese Wartezeiten gleich bleiben.
Arbeitsmenge
Eine Arbeitsmenge ist die Sammlung der Blöcke oder Seiten, die ein Programm während eines bestimmten Zeitfensters aktiv nutzt.
Zwei Blöcke einer Arbeitsmenge können in einem Eintrag konkurrieren, selbst wenn ihre Gesamtgröße unter der Cachekapazität liegt.
Array von Strukturen
Ein Array von Strukturen speichert Datensätze zusammenhängend, wobei die Felder jedes Datensatzes beieinanderliegen. Das begünstigt den Zugriff auf mehrere Felder eines Datensatzes.
Eine Teilchenaktualisierung, die Position und Geschwindigkeit gemeinsam nutzt, kann einen großen Teil der für ein Teilchen geholten Cachezeile verwenden.
ASID
Eine Adressraumkennung, kurz ASID, unterscheidet Übersetzungen verschiedener Adressräume, wenn ihre TLB-Einträge gemeinsam vorhanden sind.
Zwei Prozesse können dieselbe virtuelle Seitennummer verwenden, ohne die Übersetzung des jeweils anderen zu nutzen, wenn Einträge passende ASIDs tragen.
Auffrischung
Auffrischung ist die regelmäßige Wiederherstellung der Ladung in DRAM-Zellen, damit der Ladungsverlust ihre gespeicherten Werte nicht löscht.
Bei normalen Temperaturen umfasst die DDR4-Auffrischung ihre Zeilen innerhalb eines Zeitfensters von 64 ms; bei höheren Temperaturen ist der Zeitrahmen enger.

Ä

Änderungsbit
Ein Änderungsbit hält fest, dass ein zwischengespeicherter Block Änderungen enthält, die noch nicht an die nächste Ebene der Hierarchie weitergegeben wurden.
Ein unveränderter gültiger Block kann bei der Verdrängung verworfen werden, während bei einem veränderten gültigen Block die geänderten Daten erhalten werden müssen.

B

Bandbreite
Bandbreite ist die Datenmenge, die ein Speicherpfad pro Zeiteinheit übertragen kann; sie wird üblicherweise in Byte pro Sekunde ausgedrückt.
Ein Übertragungspfad mit 16 GB/s überträgt 64 Byte in 4 ns, sobald der Datenstrom nach seiner anfänglichen Latenz beginnt.
Basis-CPI-Wert
Der Basis-CPI-Wert sind die bereits benötigten Taktzyklen pro Befehl vor den zusätzlich modellierten Speicherwartezyklen einschließlich gewöhnlicher Cache-Treffer.
Ein Wartezeitmodell addiert Fehlzugriffsverzögerungen zum Basis-CPI-Wert, statt die Cache-Trefferzeit ein zweites Mal zu zählen.
Blockoffset
Ein Blockoffset ist die Byteposition innerhalb einer Cachezeile. Bei einer Cachezeilengröße, die eine Zweierpotenz ist, wird er durch die niederwertigsten Adressbits dargestellt.
Die niederwertigen sechs Bits einer Byteadresse wählen eine der 64 Bytepositionen innerhalb einer 64 Byte großen Cachezeile.
Byteadressierung
Die Byteadressierung weist jedem Byte eine eigene Speicheradresse zu, sodass Blocknummern durch Entfernen der Byteoffset-Information ermittelt werden.
Adressen, die sich nur in niederwertigen Offset-Bits unterscheiden, können verschiedene Bytes aus derselben gespeicherten Cachezeile auswählen.

C

Cache-Fehlzugriff
Ein Cache-Fehlzugriff tritt auf, wenn der geprüften Cacheebene eine nutzbare Kopie des angeforderten Blocks fehlt und sie ihn von unten holen muss.
Zwei abwechselnd genutzte Blöcke können wiederholt Fehlzugriffe verursachen, wenn bei direkter Abbildung jeder den anderen ersetzt.
Cache-Treffer
Ein Cache-Treffer tritt auf, wenn die geprüfte Ebene den angeforderten Block bereits in einem gültigen Eintrag mit passendem Tag enthält.
Eine Anforderung kann in L1 fehlschlagen und dennoch in L2 treffen, daher muss ihr Ergebnis für jede Ebene getrennt benannt werden.
Cache-Verschmutzung
Cache-Verschmutzung ist die Verdrängung nützlicher gespeicherter Blöcke durch Daten, die wenig Nutzen bringen, etwa durch ungenaues oder verfrühtes Prefetching.
Ein zu früher Prefetch kann eine Cachezeile belegen, die für die aktuelle Arbeit benötigt wird, und selbst vor seiner Verwendung verdrängt werden.
Cache-Zugriffsprotokoll
Ein Cache-Zugriffsprotokoll ist eine geordnete Aufzeichnung von Zugriffen und daraus folgenden Zustandsänderungen, mit der Treffer, Fehlzugriffe und Verdrängungen bestimmt werden.
Wird jeder Eintrag unmittelbar nach einem Ladevorgang aktualisiert, verwendet die nächste Zeile des Zugriffsprotokolls den richtigen gespeicherten Block.
Cacheindex
Ein Cacheindex ist das Adressfeld, das den Eintrag oder Satz auswählt, in dem ein Speicherblock liegen darf.
In einem direkt abgebildeten Cache mit vier Einträgen wählen die Blöcke 0 und 4 beide Index 0, obwohl sie unterschiedliche Tags haben.
Cachezeile
Eine Cachezeile, auch Block genannt, ist die Dateneinheit fester Größe, die ein Cache speichert und überträgt.
Eine 64 Byte große Cachezeile liefert acht benachbarte Double-Werte, selbst wenn der Zugriff, der ihr Laden auslöste, nur einen angefordert hat.
Critical Word First
Critical Word First ist eine Ladestrategie, die das angeforderte Wort vor den anderen Wörtern des Cacheblocks überträgt, um seine Wartezeit zu verkürzen.
Eine Anforderung für ein Wort nahe dem Ende einer Cachezeile kann dieses Wort zuerst erhalten, statt auf die vorhergehenden Wörter zu warten.

D

Direkt abgebildeter Cache
Ein direkt abgebildeter Cache erlaubt jedem Speicherblock genau einen Eintrag, der durch seine Blockadresse und die Anzahl der Einträge bestimmt wird.
Teilen zwei aktive Blöcke einen Eintrag, verdrängt das Laden jedes der beiden den anderen, selbst wenn andere Einträge leer sind.
DRAM
DRAM ist flüchtiger Speicher, der Bits als regelmäßig aufzufrischende Kondensatorladung speichert und dichten, bezahlbaren Hauptspeicher bereitstellt.
Ein großes Programm kann seine aktiven Seiten im DRAM halten, während kleinere Caches die am häufigsten verwendeten Cachezeilen halten.
Durchschreibverfahren
Das Durchschreibverfahren ist eine Cachestrategie, die jeden Speicherbefehl an die nächste Ebene sendet und bei einem Treffer zugleich den Cache aktualisiert, häufig mithilfe eines Schreibpuffers.
Ein Schreibpuffer kann die Aktualisierung der unteren Ebene vorübergehend halten, obwohl der Speicherbefehl den zwischengespeicherten Wert bereits verändert hat.

F

Fehlzugriffsrate
Die Fehlzugriffsrate ist der Anteil einer bestimmten Menge von Anforderungen, der seinen Block im gemessenen Cache nicht findet.
Eine Fehlzugriffsrate von 4 % wird als 0,04 eingesetzt, wenn sie bei einer AMAT-Berechnung mit einer zusätzlichen Verzögerung multipliziert wird.
Fehlzugriffsverzögerung
Die Fehlzugriffsverzögerung ist die zusätzliche Verzögerung nach der Cachesuche, die benötigt wird, um einen Block aus einer unteren Ebene zu holen, einzutragen und bereitzustellen.
Eine Suche von 2 Taktzyklen mit einer zusätzlichen Verzögerung von 80 Taktzyklen lässt einen vollständigen Fehlzugriff in einem sequenziellen Modell 82 Taktzyklen dauern.
FIFO-Ersetzung
Die FIFO-Ersetzung verdrängt den Block, der zuerst in einen Satz aufgenommen wurde, ohne die Einfügereihenfolge bei einem Treffer auf diesen Block zu ändern.
Wiederholte Treffer können den zuerst geladenen Block sehr nützlich machen, dennoch wählt FIFO ihn vor später eingetroffenen Blöcken.
Frühzeitiger Neustart
Der frühzeitige Neustart setzt den wartenden Zugriff fort, sobald sein angefordertes Wort beim Laden eines Blocks eintrifft, bevor die gesamte Cachezeile empfangen wurde.
Der Prozessor kann mit dem benötigten Wort fortfahren, während der Rest einer langen Cachezeile noch übertragen wird.

G

Gewichtete Fehlzugriffsrate
Eine gewichtete Fehlzugriffsrate kombiniert Anforderungsklassen, indem sie deren erwartete Fehlzugriffszahlen addiert und durch deren gemeinsame Anzahl von Zugriffen teilt.
Raten für Befehle und Daten müssen nach Zugriffszahlen gewichtet werden, wenn jeder Befehl weniger als eine Datenanforderung erzeugt.
Globale Fehlzugriffsrate
Eine globale Fehlzugriffsrate teilt die Fehlzugriffe einer Cacheebene durch die ursprünglichen Speicheranforderungen des Prozessors, einschließlich der oberhalb dieser Ebene bedienten Anforderungen.
L1-Fehlzugriffe von 5 % und lokale L2-Fehlzugriffe von 20 % ergeben eine globale L2-Fehlzugriffsrate von 1 %.
Gültigkeitsbit
Ein Gültigkeitsbit gehört zu den Metadaten eines Eintrags und hält fest, ob das gespeicherte Tag und die Daten einen nutzbaren zwischengespeicherten Block beschreiben.
Ein Eintrag mit passenden Tag-Bits liefert dennoch einen Fehlzugriff, wenn sein Gültigkeitsbit nach dem Start oder einer Invalidierung nicht gesetzt ist.

I

Invalidierung von Adressübersetzungen
Die Invalidierung von Adressübersetzungen verhindert, dass zwischengespeicherte Abbildungen nach relevanten Änderungen an Seitentabellen oder Adressraumzuordnungen nutzbar bleiben.
RISC-V verwendet sfence.vma, um den Zustand des Übersetzungscaches mit Aktualisierungen von Abbildungen abzustimmen.

K

Kachelung
Kachelung, auch Blockung genannt, organisiert eine Berechnung um kleine Datenbereiche, die im Cache bleiben, während ihre Werte wiederholt verwendet werden.
Drei Matrixkacheln können für viele Multiplikationen mit anschließender Addition wiederverwendet werden, bevor der Algorithmus zur nächsten Kachelgruppe übergeht.
Kapazitätsbedingter Fehlzugriff
Ein kapazitätsbedingter Fehlzugriff ist ein späterer Fehlzugriff, der auch in einem vollassoziativen LRU-Cache gleicher Kapazität mit derselben Zugriffsfolge auftritt.
Ein vollassoziativer Cache mit zwei Cachezeilen verzeichnet einen Fehlzugriff, wenn ein Zyklus aus drei Blöcken zu dem gerade verdrängten Block zurückkehrt.
Kohärenzbedingter Fehlzugriff
Ein kohärenzbedingter Fehlzugriff tritt auf, wenn ein Block fehlt, weil der Schreibzugriff eines anderen Kerns seine zwischengespeicherte Kopie invalidiert hat.
Ein Kern kann beim Zugriff auf kürzlich verwendete gemeinsam genutzte Daten einen Fehlzugriff verzeichnen, nachdem ein anderer Kern die zugehörige Cachezeile verändert hat.
Konfliktbedingter Fehlzugriff
Ein konfliktbedingter Fehlzugriff ist ein späterer Fehlzugriff, den ein vollassoziativer LRU-Cache gleicher Kapazität vermeidet, weil die flexible Platzierung den Block im Cache hält.
Ein direkt abgebildeter Eintrag kann zwischen zwei Tags wechseln, während ein assoziativer Referenzcache gleicher Größe beide Blöcke hält.

L

Latenz
Latenz ist die verstrichene Zeit von der Ausgabe einer Speicheranforderung bis zur Verfügbarkeit ihrer ersten angeforderten Daten.
Eine breite Speicherschnittstelle kann viele Bytes pro Sekunde liefern, während ein einzelner abhängiger Ladezugriff dennoch einige zehn Nanosekunden wartet.
Lokale Fehlzugriffsrate
Eine lokale Fehlzugriffsrate teilt die Fehlzugriffe einer Cacheebene nur durch die Zugriffe, die diese Ebene nach der Filterung durch obere Ebenen erreicht haben.
Eine lokale L2-Fehlzugriffsrate von 20 % beschreibt den schwierigeren Anforderungsstrom dieser Ebene, nicht 20 % aller Prozessorzugriffe.
Lokalität
Lokalität ist die Tendenz eines Programms, seine Zugriffe über kurze Zeit auf einen relativ kleinen Teil seines Adressraums zu konzentrieren.
Eine Schleife kann wiederholt einen kleinen aktiven Bereich nutzen, selbst wenn das Programm viele Gigabyte zugewiesen hat.
LRU-Ersetzung
Die LRU-Ersetzung verdrängt unter den gültigen Einträgen des ausgewählten Satzes den Block, dessen letzter Zugriff am längsten zurückliegt.
Ein Treffer aktualisiert die Nutzungsreihenfolge, obwohl er keinen neuen Block lädt. Das kann den beim nächsten Fehlzugriff zur Verdrängung gewählten Block ändern.

M

Mehrstufiger Cache
Ein mehrstufiger Cache kombiniert einen kleinen schnellen oberen Cache mit größeren unteren Caches, die viele Fehlzugriffe der oberen Ebene vor dem Hauptspeicher bedienen.
Eine Anforderung verursacht die L2-Suche nur bei einem L1-Fehlzugriff, sodass die verschachtelte AMAT diese Suche mit dem L1-Fehlzugriffsanteil gewichtet.
Mittlere Speicherzugriffszeit
Die mittlere Speicherzugriffszeit ist die erwartete Verzögerung pro Speicheranforderung. Sie kombiniert die Suchzeit mit den wahrscheinlichkeitsgewichteten zusätzlichen Fehlzugriffskosten.
Eine langsamere Suche kann den Nutzen geringerer Fehlzugriffszahlen aufheben, wenn die eingesparte Verzögerung der unteren Ebene gering ist.

N

NAND-Flash
NAND-Flash ist ein nichtflüchtiger Speicher, der Seiten liest und programmiert, größere Blöcke löscht und nur eine begrenzte Anzahl von Programmier- und Löschzyklen übersteht.
Ein SSD-Controller bildet aktualisierte logische Daten auf verfügbaren Flash-Speicherplatz ab, statt Flash wie byteweise beschreibbares DRAM zu behandeln.
Nichtblockierender Cache
Ein nichtblockierender Cache erlaubt es, andere Treffer oder weitere Fehlzugriffe zu bearbeiten, während eine oder mehrere Blockanforderungen ausstehen.
Ein Prozessor mit Ausführung außerhalb der Befehlsreihenfolge kann einen unabhängigen Ladezugriff aus dem Cache bedienen, während ein anderer auf das Laden aus dem DRAM wartet.
No-Write-Allocate-Verfahren
Das No-Write-Allocate-Verfahren ist eine Strategie bei Schreibfehlzugriffen, die den Speicherbefehl nach unten sendet, ohne seinen Block im geprüften Cache einzutragen.
Ein einmaliger Ausgabestrom kann vermeiden, wiederverwendbare zwischengespeicherte Daten zu verdrängen, wenn seine Schreibfehlzugriffe keine Zuweisung auslösen.

O

Obligatorischer Fehlzugriff
Ein obligatorischer Fehlzugriff ist ein Fehlzugriff beim ersten Zugriff auf einen Block in der Zugriffsfolge, den eine größere Cachekapazität allein nicht vermeiden kann.
Der erste Zugriff auf Anforderung auf jede Cachezeile eines sequenziellen Arraydurchlaufs mit zunächst leerem Cache ist ohne Vorausladen obligatorisch.

P

Padding
Padding fügt ungenutzten Speicherplatz zwischen logischen Datenbereichen hinzu und kann dadurch Adressschrittweiten und die Abbildung dieser Bereiche auf Cachesätze ändern.
Das Hinzufügen von acht Double-Werten zu einer Zeilenlänge, die eine Zweierpotenz ist, kann aufeinanderfolgende Zeilenanfänge auf verschiedene Sätze verteilen.
Physische Seitennummer
Eine physische Seitennummer bezeichnet den von einer Abbildung verwendeten physischen Seitenrahmen und bildet den höherwertigen Teil der übersetzten Byteadresse.
Die physische Byteadresse ist die Basisadresse des Seitenrahmens plus der unveränderte Seitenoffset, nicht die unverschobene Seitenrahmennummer plus Offset.
Prefetching
Prefetching fordert Daten an, bevor ein Zugriff auf Anforderung sie benötigt, sodass sich bei rechtzeitiger Anforderung die Übertragungslatenz mit nützlicher Arbeit überlappen kann.
Ein Prefetcher für Datenströme kann spätere Arrayzeilen vorbereiten, aber ungenaue Anforderungen verbrauchen weiterhin Bandbreite und Cacheplatz.
Pseudo-LRU
Pseudo-LRU ist ein näherungsweises Ersetzungsverfahren, das weniger Zustand als exaktes LRU speichert und zugleich versucht, kürzlich verwendete Blöcke zu bevorzugen.
Hochassoziative Caches nähern die Nutzungsreihenfolge oft an, weil das Speichern einer vollständigen Reihenfolge mehr Hardware kostet.

R

Räumliche Lokalität
Räumliche Lokalität ist die Tendenz, auf Adressen nahe einer kürzlich verwendeten Adresse zuzugreifen, wodurch benachbarte Bytes nützlich werden.
Ein sequenzieller Arraydurchlauf kann die übrigen Werte einer Cachezeile nutzen, nachdem der erste Wert sie in den Cache gebracht hat.
Rückschreibverfahren
Das Rückschreibverfahren ist eine Cachestrategie, die Speicherbefehle in einem als verändert markierten zwischengespeicherten Block festhält und diesen bei seiner Verdrängung nach unten sendet.
Viele Speicherbefehle für eine gespeicherte Cachezeile können beim Ersetzen der Cachezeile zu einer ausgehenden Blockübertragung zusammengefasst werden.

S

Satzassoziativer Cache
Ein satzassoziativer Cache bildet einen Block auf einen Satz ab, erlaubt ihm aber, jeden von mehreren Einträgen dieses Satzes zu belegen, die Wege genannt werden.
Zwei Blöcke mit demselben Index können in einem 2-fach assoziativen Satz gemeinsam liegen und so Verdrängungen vermeiden, die bei direkter Abbildung nötig wären.
Schleifenvertauschung
Die Schleifenvertauschung tauscht die Verschachtelungsreihenfolge von Schleifen, um den Durchlauf zu ändern und dabei das erforderliche Verhalten der Berechnung zu erhalten.
Die Änderung, welcher Matrixindex am schnellsten durchlaufen wird, kann einen Spaltenstrom in einen Zeilenstrom verwandeln, ohne die Rechenarbeit zu verringern.
Schreibpuffer
Ein Schreibpuffer ist eine endliche Warteschlange für ausstehende Schreibzugriffe auf eine untere Ebene, sodass die Ausführung fortgesetzt werden kann, bevor diese abgeschlossen sind.
Eine lange Folge von Speicherbefehlen füllt den Puffer, wenn das Ziel Aktualisierungen nicht so schnell abarbeiten kann, wie sie eintreffen.
Schrittweite
Eine Schrittweite ist der Adressunterschied zwischen aufeinanderfolgenden Zugriffen eines Durchlaufs, gemessen in Byte oder mit angegebener Einheit in Elementen.
Ein spaltenweiser Durchlauf einer zeilenweise gespeicherten Matrix rückt um die Bytelänge einer Zeile statt um die Größe eines Elements weiter.
Seitenfehler
Ein Seitenfehler ist eine Ausnahme, die entsteht, wenn die Seitenübersetzung oder Berechtigungsprüfungen für einen Zugriff nicht normal abgeschlossen werden können.
Ein verbotener Speicherbefehl kann bei einer vorhandenen Seite einen Seitenfehler auslösen, während manche fehlenden Abbildungen ohne Lesen aus dem Massenspeicher aufgelöst werden.
Seitenoffset
Ein Seitenoffset ist die Byteposition innerhalb einer Seite, die erhalten bleibt, wenn ihre virtuelle Seitennummer in eine physische Seitennummer übersetzt wird.
Zwei Adressen auf derselben Seite teilen eine Übersetzung, während ihre unterschiedlichen Offsets verschiedene Bytes auswählen.
Seitenrahmen
Ein Seitenrahmen ist ein Platz von Seitengröße im physischen Hauptspeicher, der den Inhalt einer darauf abgebildeten virtuellen Seite aufnehmen kann.
Zwei Prozesse können Daten gezielt gemeinsam nutzen, indem sie ausgewählte virtuelle Seiten auf denselben physischen Seitenrahmen abbilden.
Seitentabellendurchlauf
Ein Seitentabellendurchlauf liest nach einem TLB-Fehlzugriff die für die Adressübersetzung benötigten Abbildungseinträge und prüft, ob die Abbildung den Zugriff erlaubt.
Ein erfolgreicher Seitentabellendurchlauf füllt den TLB nach, während eine fehlende oder unzulässige Abbildung einen Seitenfehler auslösen kann.
Seitentabelleneintrag
Ein Seitentabelleneintrag hält Übersetzungsinformationen wie eine physische Seitennummer, Gültigkeit, Berechtigungen sowie Zugriffs- oder Änderungszustand fest.
Eine im Hauptspeicher vorhandene Seite kann einen Speicherbefehl dennoch zurückweisen, wenn ihr PTE Lesezugriffe erlaubt, aber keinen Schreibzugriff gewährt.
Speicherbank
Eine Speicherbank ist ein getrennt gesteuertes DRAM-Feld aus Zeilen und Spalten, dessen Operationen sich mit denen anderer Bänke überlappen können.
Die Verschränkung von Anforderungen über mehrere Bänke kann die bereitgestellte Bandbreite erhöhen, während eine Bank auf eine Zeilenoperation wartet.
Speicherbedarf der Kacheln
Der Speicherbedarf der Kacheln ist der Speicherplatz, den alle Kacheln belegen, die gemeinsam im Cache liegen müssen, damit eine gekachelte Berechnung ihre beabsichtigte Wiederverwendung erreicht.
Drei Kacheln aus Double-Werten mit je 32 × 32 Elementen belegen 24 KiB und lassen in einem Cache mit 32 KiB etwas Platz für andere aktive Daten.
Speicherhierarchie
Eine Speicherhierarchie ist eine Anordnung von Speicherebenen, die kleine schnelle mit größeren langsamen Speichern kombiniert, um die Lokalität von Programmen zu nutzen.
Ein L1-Fehlzugriff kann von L2 bedient werden, bevor die Anforderung die viel längere Verzögerung eines DRAM-Zugriffs verursacht.
Speicherwartezyklen pro Befehl
Speicherwartezyklen pro Befehl sind die zusätzlichen, dem Warten auf den Speicher zugeschriebenen Taktzyklen pro Befehl, wobei Überlappung entsprechend dem Zeitmodell behandelt wird.
Eine Fehlzugriffsanzahl von 0,02 pro Befehl und eine nicht überlappte Verzögerung von 100 Taktzyklen fügen dem gesamten CPI-Wert zwei Taktzyklen hinzu.
SRAM
SRAM ist flüchtiger Speicher, der Bits in stabilen stromversorgten Schaltungen ohne regelmäßige Auffrischung hält und häufig für schnelle Caches verwendet wird.
Ein Cache auf dem Chip verwendet SRAM, um eine niedrige Latenz zu bieten und eine kleine Menge häufig genutzter Daten zu halten.
Struktur von Arrays
Eine Struktur von Arrays speichert jedes Datensatzfeld in einem eigenen zusammenhängenden Array und begünstigt so das Durchlaufen dieses Feldes über viele Datensätze hinweg.
Das Summieren nur horizontaler Positionen kann ein dicht gepacktes Positionsarray laden, ohne die anderen Felder jedes Teilchens zu laden.

T

Tag
Ein Tag ist die mit einem Cacheeintrag gespeicherte höherwertige Adressinformation, die angibt, welcher Block den ausgewählten Eintrag oder Satz belegt.
Derselbe Index kann sich auf viele Speicherblöcke beziehen, sodass ein Tag-Vergleich den aktuell zwischengespeicherten Block unterscheidet.
Taktperiode
Die Taktperiode ist die Dauer eines Prozessortaktzyklus. Sie ist der Kehrwert der Taktfrequenz und wird verwendet, um den CPI-Wert in Zeit umzurechnen.
Eine Verdopplung der Taktfrequenz halbiert die Taktperiode, verdoppelt aber die Anzahl der Taktzyklen einer unveränderten DRAM-Verzögerung.
Thrashing
Thrashing ist das wiederholte Verdrängen und erneute Laden aktiv benötigter Blöcke, das viele Fehlzugriffe erzeugt, weil die Blöcke nicht gemeinsam im Cache bleiben können.
Das zyklische Durchlaufen von drei Blöcken in einem 2-fach assoziativen LRU-Satz kann jeden Block kurz vor seiner nächsten Verwendung verdrängen.
TLB
Ein Translation Lookaside Buffer, kurz TLB, speichert kürzlich verwendete Übersetzungen virtueller Seiten und zugehörige Berechtigungen zwischen, um wiederholte Seitentabellendurchläufe zu vermeiden.
Ein TLB-Treffer kann dennoch mit einem Datencache-Fehlzugriff einhergehen, weil das Vorhandensein einer Abbildung sich vom Vorhandensein einer Datenzeile unterscheidet.
TLB-Reichweite
Die TLB-Reichweite ist der gesamte durch die verfügbaren Übersetzungen dargestellte Adressbereich. Bei gleich großen Seiten wird sie als Anzahl der Einträge mal Seitengröße berechnet.
Ein TLB mit 64 Einträgen deckt bei 4-KiB-Seiten 256 KiB ab, selbst wenn eine Schleife nur wenige Bytes jeder Seite berührt.
Trefferrate
Die Trefferrate ist die Anzahl der Zugriffe, die ihren Block in der geprüften Ebene finden, geteilt durch alle Zugriffe auf diese Ebene.
Neunzig Treffer bei hundert Cacheanforderungen ergeben eine Trefferrate von 90 % und eine ergänzende Fehlzugriffsrate von 10 %.
Trefferzeit
Die Trefferzeit ist die Verzögerung für den Zugriff auf eine Cacheebene und die Feststellung, ob ein Treffer vorliegt. Sie umfasst die Suche, die auch bei Fehlzugriffen erfolgt.
Eine Suche von 2 Taktzyklen fügt jeder Anforderung zwei Taktzyklen hinzu, bevor eine zusätzliche Fehlzugriffsverzögerung gezählt wird.

V

VIPT-Cache
Ein virtuell indizierter und physisch getaggter Cache beginnt die Satzsuche mit virtuellen Adressbits und prüft die Identität anhand eines übersetzten physischen Tags.
Ein 8-fach assoziativer L1-Cache mit 32 KiB kann seine Satzindex- und Cachezeilenoffset-Bits innerhalb des Offsets einer 4-KiB-Seite unterbringen.
Virtuelle Seitennummer
Eine virtuelle Seitennummer ist der höherwertige Teil einer virtuellen Adresse, der die Seite bezeichnet, deren Abbildung die Übersetzung beschaffen muss.
Bei 4-KiB-Seiten bleibt nach dem Entfernen der niederwertigen 12 Offset-Bits die für die Übersetzung verwendete virtuelle Seitennummer.
Virtueller Speicher
Virtueller Speicher bildet Prozessadressen auf physischen Speicher ab und unterstützt dabei Schutz, kontrollierte gemeinsame Nutzung und Seiten im Massenspeicher.
Ein Prozess verwendet weiterhin virtuellen Speicher, wenn alle seine aktiven Seiten in den DRAM passen und er nichts auslagert.
Vollassoziativer Cache
Ein vollassoziativer Cache hat einen Satz mit allen Einträgen und erlaubt jedem Block, ohne Indexfeld jeden Eintrag zu belegen.
Ein vollassoziativer LRU-Cache gleicher Kapazität dient als Referenz, um konfliktbedingte von kapazitätsbedingten Fehlzugriffen zu unterscheiden.

W

Wear-Leveling
Wear-Leveling ist ein Verfahren des Controllers, das Schreib- und Löschvorgänge im Flash-Speicher auf physische Blöcke verteilt, um den Zellverschleiß zu verteilen.
Wiederholte Aktualisierungen eines logischen Datensatzes können in verschiedenen physischen Blöcken abgelegt werden, damit nicht ein Speicherplatz verschleißt.
Weg
Ein Weg ist einer der verfügbaren Cacheeinträge innerhalb eines Satzes; jeder kann einen Datenblock mit eigenem Tag halten.
Ein 8-fach assoziativer Satz kann acht konkurrierende Blöcke halten, bevor ein neuer Ladevorgang einen gültigen Block zur Verdrängung wählen muss.
Write-Allocate-Verfahren
Das Write-Allocate-Verfahren ist eine Strategie bei Schreibfehlzugriffen, die den fehlenden Block in den Cache holt und dann den Speicherbefehl auf diesen Block anwendet.
Ein späterer Lesezugriff kann in der Cachezeile treffen, die ein früherer zuweisender Speicherbefehl für ein anderes Byte desselben Blocks geladen hat.

Z

Zeilenpuffer
Ein Zeilenpuffer ist eine Schaltung, die eine aktivierte DRAM-Zeile hält, sodass Zugriffe Spalten auswählen können, ohne diese Zeile erneut zu öffnen.
Wiederholte Anforderungen an eine bereits geöffnete Zeile vermeiden das Vorladen und Aktivieren, das für einen Zeilenwechsel in dieser Bank nötig ist.
Zeilenweise Speicherung
Zeilenweise Speicherung legt die Elemente jeder Zeile eines rechteckigen Arrays zusammenhängend ab und platziert aufeinanderfolgende Zeilen nacheinander.
In einem C-Array a[i][j] durchläuft die Änderung von j in der inneren Schleife benachbarte Elemente einer Zeile.
Zeitliche Lokalität
Zeitliche Lokalität ist die Tendenz, kurz nach einem früheren Zugriff erneut auf denselben Befehl oder dasselbe Datenelement zuzugreifen.
Die Befehle innerhalb einer kurzen Schleife werden wiederholt geholt, während die Schleife aufeinanderfolgende Elemente verarbeitet.

Über diese Einheit

Von StudeliFehler melden

Erstelle deine eigenen Lernmaterialien

Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.

Jetzt starten