Hier ist ein Screenshot eines Cache-Benchmarks:
Im Benchmark liegt die Lesegeschwindigkeit des L1-Cache bei ca. 186 GB / s, wobei die Latenz bei ca. 3-4 Taktzyklen liegt. Wie wird eine solche Geschwindigkeit überhaupt erreicht?
Betrachten Sie den Speicher hier: Die theoretische maximale Geschwindigkeit beträgt 665 MHz (Speicherfrequenz) x 2 (doppelte Datenrate) x 64 Bit (Busbreite), was ungefähr 10,6 GB / s entspricht, was näher am Benchmark-Wert von 9,6 GB / s liegt .
Aber mit dem L1-Cache würden wir, selbst wenn wir bei jedem Zyklus mit dem Prozessor bei seiner Maximalfrequenz (3 GHz) lesen könnten, ungefähr 496 Datenleitungen benötigen, um einen solchen Durchsatz zu erzielen, der unrealistisch klingt. Dies gilt auch für andere Caches.
Was vermisse ich? Wie berechnen wir den Durchsatz eines Caches anhand seiner Parameter?
quelle
Antworten:
Diese CPU hat ...
Da es zwei Kerne gibt, können wir davon ausgehen, dass der Benchmark zwei Threads parallel ausführt. Ihre Website liefert zwar bemerkenswert wenig Informationen, aber wenn wir hier nachsehen , scheinen CPUs mit mehr Kernen entsprechend höhere L1-Durchsätze zu liefern. Ich denke, was angezeigt wird, ist der Gesamtdurchsatz, wobei alle Kerne parallel arbeiten. Für Ihre CPU sollten wir also für einen Kern und einen Cache durch zwei teilen:
Die Tatsache, dass "copy" 2x schneller ist als "write", ist höchst verdächtig. Wie könnte es schneller kopieren als schreiben? Ich gehe davon aus, dass das, was der Benchmark als "Kopie" anzeigt, die Summe aus Lese- und Schreibdurchsatz ist. In diesem Fall würde es sowohl lesen als auch schreiben mit 45 GB / s, aber 90 anzeigen, da es sich um einen Benchmark handelt, und Wer zum Teufel vertraut Benchmarks? Ignorieren wir also "copy".
Jetzt ist ein 128-Bit-Register 16 Bytes groß und nahe genug, sodass dieser Cache anscheinend zwei 128-Bit-Lesevorgänge und einen Schreibvorgang pro Takt ausführen kann.
Dies ist genau das, was Sie wirklich tun möchten, um die SSE-Anweisungen zur Zahleneingabe zu optimieren: zwei Lesevorgänge und ein Schreibvorgang pro Zyklus.
Dies würde höchstwahrscheinlich mit vielen parallelen Datenleitungen implementiert werden, was der übliche Weg ist, um viele Daten innerhalb eines Chips sehr schnell zu transportieren.
quelle
a[i] = b[i] + c[i]
). Übrigens, Intel Haswell und später haben eine Store-AGU an Port 7, die einfache (nicht indizierte) Adressierungsmodi verarbeiten kann, sodass sie 2 Lade- + 1-Speicher-Uops pro Takt ausführen können. (Und der Datenpfad zu L1D ist 256b, also verdoppelt er die L1D-Bandbreite.) Siehe David Kanters ArtikelDie Antwort von @ peufeu weist darauf hin, dass dies systemweite Gesamtbandbreiten sind. L1 und L2 sind private Pro-Core-Caches in der Intel Sandybridge-Familie. Die Zahlen sind also doppelt so hoch wie die eines einzelnen Cores. Wir haben aber trotzdem eine beeindruckend hohe Bandbreite und eine geringe Latenz.
Der L1D-Cache ist direkt in den CPU-Kern integriert und sehr eng mit den Lade-Ausführungseinheiten (und dem Speicherpuffer) verbunden . In ähnlicher Weise befindet sich der L1I-Cache direkt neben dem Befehlsabruf- / Dekodierteil des Kerns. (Ich habe mir noch keinen Sandybridge-Silizium-Grundriss angesehen, daher trifft dies möglicherweise nicht wirklich zu. Der Ausgabe- / Umbenennungsteil des Front-Ends befindet sich wahrscheinlich näher am mit "L0" dekodierten UOP-Cache, der Strom spart und eine bessere Bandbreite aufweist als die Decoder.)
Warum dort aufhören? Intel seit Sandybridge und AMD seit K8 können 2 Ladevorgänge pro Zyklus ausführen. Multi-Port-Caches und TLBs sind eine Sache.
Die Sandybridge-Mikroarchitektur von David Kanter enthält ein schönes Diagramm (das auch für Ihre IvyBridge-CPU gilt):
(Der "Unified Scheduler" hält ALUs und Speicher-Uops bereit, bis ihre Eingaben bereit sind, und / oder wartet auf ihren Ausführungsport. (
vmovdqa ymm0, [rdi]
Dekodiert z. B. in einen Lade-Uop, auf den gewartet werden muss,rdi
wenn ein vorherigeradd rdi,32
noch nicht ausgeführt wurde.) Beispiel: Intel plant Uops zu Ports zum Zeitpunkt der Ausgabe / Umbenennung . Dieses Diagramm zeigt nur die Ausführungsports für Speicher-Uops, aber nicht ausgeführte ALU-Uops konkurrieren auch darum. Die Ausgabe- / Umbenennungsphase fügt Uops zu ROB und Scheduler hinzu Sie bleiben bis zur Stilllegung im ROB, aber nur bis zum Versand an einen Ausführungsport im Scheduler. AMD verwendet separate Scheduler für Integer / FP, Adressierungsmodi verwenden jedoch immer Integer-RegisterWie das zeigt, gibt es nur 2 AGU-Ports (Adressgenerierungseinheiten, die einen Adressierungsmodus annehmen
[rdi + rdx*4 + 1024]
und eine lineare Adresse erzeugen). Es kann 2 Speicheroperationen pro Takt ausführen (von jeweils 128 b / 16 Bytes), von denen eine ein Speicher ist.Aber es hat einen Trick auf Lager: SnB / IvB-Lauf 256b AVX lädt / speichert als einzelnes UOP, das 2 Zyklen in einem Lade- / Speicher-Port benötigt, aber nur die AGU im ersten Zyklus benötigt. Auf diese Weise kann eine Speicheradresse uop in diesem zweiten Zyklus auf der AGU an Port 2/3 ausgeführt werden, ohne dass der Ladedurchsatz verloren geht. Mit AVX (die von Intel Pentium / Celeron-CPUs nicht unterstützt werden: /) kann SnB / IvB (theoretisch) 2 Ladevorgänge und 1 Speicher pro Zyklus aushalten .
Ihre IvyBridge-CPU ist der Schrumpf von Sandybridge (mit einigen Verbesserungen der Mikroarchitektur, z. B. Mov-Elimination , ERMSB (memcpy / memset) und Hardware-Prefetching auf der nächsten Seite). Die nachfolgende Generation (Haswell) verdoppelte die L1D-Bandbreite pro Takt, indem die Datenpfade von Ausführungseinheiten auf L1 von 128b auf 256b erweitert wurden, sodass die AVX 256b-Lasten 2 pro Takt aushalten können. Es wurde auch ein zusätzlicher Store-AGU-Port für einfache Adressierungsmodi hinzugefügt.
Der Spitzendurchsatz von Haswell / Skylake liegt bei 96 geladenen und gespeicherten Bytes pro Takt. Das Optimierungshandbuch von Intel geht jedoch davon aus, dass der anhaltende durchschnittliche Durchsatz von Skylake (immer noch keine L1D- oder TLB-Fehler vorausgesetzt) ~ 81B pro Zyklus beträgt. (A skalare Ganzzahl - Schleife kann Sustain 2 Lasten + 1 Speicher pro Takt nach meiner Prüfung auf SKL, Ausführen 7 (nicht - fusionierten-Domäne) UOPs pro Takt von 4 anellierten Domäne uops. Aber es verlangsamt sich etwas mit 64-Bit - Operanden , anstatt 32-Bit, es gibt also anscheinend ein gewisses Limit an Ressourcen für Mikroarchitekturen, und es geht nicht nur darum, die Speicheradress-Uops auf Port 2/3 zu planen und Zyklen von Lasten zu stehlen.)
Dies ist nicht möglich, es sei denn, die Parameter enthalten praktische Durchsatzzahlen. Wie oben erwähnt, kann selbst die L1D von Skylake mit ihren Lade- / Speicher-Ausführungseinheiten für 256b-Vektoren nicht ganz mithalten. Obwohl es in der Nähe ist und es für 32-Bit-Ganzzahlen kann. (Es wäre nicht sinnvoll, mehr Ladeeinheiten zu haben, als der Cache über Leseports verfügt, oder umgekehrt. Sie würden nur Hardware weglassen, die niemals vollständig genutzt werden könnte. Beachten Sie, dass L1D möglicherweise zusätzliche Ports zum Senden / Empfangen von Leitungen hat / von anderen Kernen sowie für Lese- / Schreibvorgänge innerhalb des Kerns.)
Wenn Sie sich nur die Datenbusbreiten und -uhren ansehen, können Sie nicht die ganze Geschichte erzählen. Die Bandbreite von L2 und L3 (und des Speichers) kann durch die Anzahl der ausstehenden Fehler begrenzt werden, die L1 oder L2 nachverfolgen können . Die Bandbreite darf die Latenz * max_concurrency nicht überschreiten, und Chips mit einer höheren Latenz L3 (wie ein Xeon mit vielen Kernen) haben eine viel geringere Single-Core-L3-Bandbreite als eine Dual- / Quad-Core-CPU derselben Mikroarchitektur. Siehe den Abschnitt "Latenz-gebundene Plattformen" in dieser SO-Antwort . CPUs der Sandybridge-Familie verfügen über 10 Line-Fill-Puffer zum Verfolgen von L1D-Fehlern (auch von NT-Speichern verwendet).
(Die gesamte L3 / Speicher-Bandbreite mit vielen aktiven Kernen ist auf einem großen Xeon sehr groß, aber Single-Threaded-Code hat bei gleicher Taktrate eine schlechtere Bandbreite als auf einem Quad-Core, da mehr Kerne mehr Stopps auf dem Ringbus bedeuten und damit höher Latenz L3.)
Cache-Latenz
Die Latenzzeit des L1D-Caches beim Laden mit 4 Zyklen ist ziemlich erstaunlich , vor allem, wenn man bedenkt, dass er mit einem Adressierungsmodus beginnen
[rsi + 32]
muss, also muss er addieren, bevor er überhaupt eine virtuelle Adresse hat. Dann muss es das in physisch übersetzen, um die Cache-Tags auf eine Übereinstimmung zu überprüfen.(Für andere Adressierungsmodi als
[base + 0-2047]
die Intel Sandybridge-Familie ist ein zusätzlicher Zyklus erforderlich. Daher gibt es in den AGUs eine Abkürzung für einfache Adressierungsmodi (typisch für Zeigerjagd-Fälle, in denen eine geringe Latenz bei Last wahrscheinlich am wichtigsten ist, aber auch allgemein üblich). (Siehe Intels Optimierungshandbuch , Sandybridge, Abschnitt 2.3.5.2 L1 DCache.) Dies setzt auch keine Segmentüberschreibung und eine0
normale Segmentbasisadresse von voraus .)Außerdem muss der Speicherpuffer überprüft werden, um festzustellen, ob er sich mit früheren Speichern überschneidet. Und es muss dies herausfinden, auch wenn eine frühere (in Programmreihenfolge) Speicheradresse uop noch nicht ausgeführt wurde, so dass die Speicheradresse nicht bekannt ist. Dies kann jedoch vermutlich parallel zur Überprüfung auf einen L1D-Treffer geschehen. Wenn sich herausstellt, dass die L1D-Daten nicht benötigt wurden, weil die Speicherweiterleitung die Daten aus dem Speicherpuffer bereitstellen kann, ist dies kein Verlust.
Intel verwendet VIPT-Caches (Virtually Indexed Physically Tagged) wie fast alle anderen. Dabei wird der Standardtrick angewendet, bei dem der Cache so klein und assoziativ ist, dass er sich wie ein PIPT-Cache (kein Aliasing) mit der Geschwindigkeit von VIPT verhält (kann indizieren) parallel zur virtuellen -> physischen Suche des TLB).
Die L1-Caches von Intel sind 8-Wege-Assoziativ-Caches mit 32 KB. Die Seitengröße beträgt 4kB. Dies bedeutet, dass die "Index" -Bits (mit denen ausgewählt wird, auf welche 8 Arten eine bestimmte Zeile zwischengespeichert werden kann) alle unterhalb des Seitenversatzes liegen. Das heißt, diese Adressbits sind der Versatz in einer Seite und sind in der virtuellen und der physischen Adresse immer gleich.
Weitere Einzelheiten dazu und weitere Einzelheiten dazu, warum kleine / schnelle Caches nützlich / möglich sind (und gut funktionieren, wenn sie mit größeren langsameren Caches kombiniert werden ), finden Sie in meiner Antwort zur Frage, warum L1D kleiner / schneller als L2 ist .
Kleine Caches können Dinge erledigen, die in größeren Caches zu energieintensiv wären, z. B. das Abrufen der Daten-Arrays von einem Satz zur gleichen Zeit wie das Abrufen von Tags. Sobald ein Komparator herausfindet, welches Tag passt, muss er nur eine der acht 64-Byte-Cache-Zeilen muxen, die bereits aus dem SRAM abgerufen wurden.
(Ganz so einfach ist das nicht: Sandybridge / Ivybridge verwenden einen L1D-Cache mit einer Anzahl von 16-Byte-Blöcken. Sie können Cache-Bank-Konflikte erhalten, wenn zwei Zugriffe auf dieselbe Bank in verschiedenen Cache-Zeilen im selben Zyklus ausgeführt werden sollen. (Es gibt 8 Bänke, dies kann also bei Adressen geschehen, die ein Vielfaches von 128 voneinander entfernt sind, dh 2 Cache-Zeilen.)
IvyBridge hat auch keine Strafe für nicht ausgerichteten Zugriff, solange es nicht eine 64B-Cache-Zeilengrenze überschreitet. Ich vermute, es wird anhand der niedrigen Adressbits herausgefunden, welche Bank (en) abgerufen werden sollen, und es wird die Verschiebung festgelegt, die erforderlich ist, um die korrekten Daten von 1 bis 16 Byte zu erhalten.
Bei Cache-Zeilensplits ist es immer noch nur ein einziges UOP, führt jedoch mehrere Cache-Zugriffe aus. Die Strafe ist immer noch gering, außer bei 4k-Splits. Skylake macht sogar 4k-Splits mit einer Latenz von ungefähr 11 Zyklen ziemlich billig, genau wie ein normaler Cache-Line-Split mit einem komplexen Adressierungsmodus. Der 4k-Split-Durchsatz ist jedoch deutlich schlechter als der von Cl-Split-Non-Split.
Quellen :
quelle
Bei modernen CPUs befindet sich der Cache-Speicher direkt neben der CPU auf dem gleichen Chip (Chip) . Er wird mit SRAM erstellt , der viel schneller ist als der DRAM, der für die RAM-Module in einem PC verwendet wird.
Pro Speichereinheit (ein Bit oder Byte) ist SRAM viel teurer als DRAM. Deshalb wird DRAM auch in einem PC verwendet.
Da SRAM jedoch in der gleichen Technologie wie die CPU selbst hergestellt wird, ist es so schnell wie die CPU. Außerdem gibt es nur interne Busse (auf der CPU), die behandelt werden müssen. Wenn es sich also um einen 496 Zeilen breiten Bus handelt, ist dies wahrscheinlich der Fall.
quelle
L1-Caches sind ziemlich breite Speicherstrukturen. Die Architektur der L1-Caches in Intel-Prozessoren finden Sie in diesem Handbuch (bereitgestellt von next-hack). Die Interpretation einiger Parameter ist jedoch falsch. Die "Cache-Zeilengröße" ist nicht die "Datenbreite", sondern die Größe des seriellen Blocks für den atomaren Datenzugriff.
Tabelle 2-17 (Abschnitt 2.3.5.1) gibt an, dass beim Laden (Lesen) die Cache-Bandbreite 2x16 = 32 Bytes pro Core und CYCLE beträgt . Dies allein ergibt eine theoretische Bandbreite von 96 Gbit / s auf einem 3GHz-Kern. Es ist nicht klar, was der zitierte Benchmark angibt, es sieht so aus, als würden zwei parallel arbeitende Kerne gemessen, sodass 192 Gbit / s für zwei Kerne entstehen.
quelle
Gate-Delays sind was? 10 Pikosekunden? Die Zykluszeiten für gesamte Pipeline-Operationen betragen 333 Pikosekunden, wobei verschiedene Dekodierungs- und Busaktivitäten und das Flip-Flop-Greifen von Daten erfolgen, bevor der nächste Taktzyklus beginnt.
Ich gehe davon aus, dass die langsamste Aktivität beim Lesen eines Caches darauf wartet, dass sich die Datenzeilen weit genug voneinander entfernen (wahrscheinlich sind dies Differentiale: eine Referenz und eine tatsächliche Ladung vom Lesebit), dass ein Komparator / Latch getaktet werden kann, um ein positives Signal zu implementieren. Rückkopplungsaktion, um eine winzige Spannung in einen großen Spannungshub von Schiene zu Schiene (ca. 1 Volt) umzuwandeln.
quelle
[reg + 0-2047]
) und eine TLB-Suche sowie einen Tag-Vergleich (8-Wege-Assoziativ) umfasst und die resultierenden bis zu 16 nicht ausgerichteten Bytes auf die Ausgabeport der Ladeeinheit zur Weiterleitung an andere Ausführungseinheiten. Es ist 4c Latenz für eine Pointer-Chasing-Schleife wiemov rax, [rax]
.