Hier ist ein Screenshot eines Cache-Benchmarks:
Im Benchmark liegt die Lesegeschwindigkeit des L1-Cache bei etwa 186 GB/s, wobei die Latenz etwa 3-4 Taktzyklen beträgt. Wie wird eine solche Geschwindigkeit überhaupt erreicht?
Betrachten Sie hier den Speicher: Die theoretische Höchstgeschwindigkeit beträgt 665 MHz (Speicherfrequenz) x 2 (doppelte Datenrate) x 64 Bit (Busbreite), was etwa 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 der maximalen Prozessorfrequenz (3 GHz) lesen könnten, etwa 496 Datenleitungen benötigen, um einen solchen Durchsatz zu erreichen, was unrealistisch klingt. Dies gilt auch für andere Caches.
Was vermisse ich? Wie berechnen wir den Durchsatz eines Caches aus seinen Parametern?
Diese CPU hat...
2 Kerne Ein 32-KB-Anweisungs- und 32-KB-Daten-Cache der ersten Ebene (L1) für jeden Kern
Da es zwei Kerne gibt, können wir davon ausgehen, dass der Benchmark zwei Threads parallel laufen lässt. Ihre Website gibt zwar bemerkenswert wenig Informationen, aber wenn wir hier nachsehen , scheinen CPUs mit mehr Kernen entsprechend höhere L1-Durchsätze zu liefern. Ich denke also, was angezeigt wird, ist der Gesamtdurchsatz, wenn alle Kerne parallel arbeiten. Für Ihre CPU sollten wir also für einen Kern und einen Cache durch zwei teilen:
Read 93 GB/s
Write 47 GB/s
Copy 90 GB/s
Nun, die Tatsache, dass "Kopieren" 2x schneller ist als "Schreiben", ist höchst verdächtig. Wie könnte es schneller kopieren als schreiben? Ich wette, dass das, was der Benchmark als „Kopie“ anzeigt, die Summe des Lese- und Schreibdurchsatzes ist, und in diesem Fall würde es sowohl mit 45 GB/s lesen als auch schreiben, aber 90 anzeigen, weil es ein Benchmark ist, und Wer zum Teufel vertraut Benchmarks? Ignorieren wir also "Kopieren".
Read 93 GB/s => 30 bytes/clock
Write 47 GB/s => 15 bytes/clock
Nun, ein 128-Bit-Register ist 16 Bytes groß, nahe genug, also klingt es so, als ob dieser Cache zwei 128-Bit-Lesevorgänge und einen Schreibvorgang pro Takt ausführen kann.
Das ist genau das, was Sie wollen, um diese SSE-Anweisungen zum Knacken von Zahlen wirklich zu rationalisieren: zwei Lesevorgänge und ein Schreibvorgang pro Zyklus.
Dies würde höchstwahrscheinlich mit vielen parallelen Datenleitungen implementiert, was der übliche Weg ist, um viele Daten sehr schnell innerhalb eines Chips herumzuschleppen.
a[i] = b[i] + c[i]
). Übrigens haben Intel Haswell und später eine Speicher-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 sich die L1D-Bandbreite.) Siehe David Kanters Artikel: realworldtech.com/haswell-cpu/5Die Antwort von @peufeu weist darauf hin, dass dies systemweite aggregierte Bandbreiten sind. L1 und L2 sind private Caches pro Kern in der Intel Sandybridge-Familie, die Zahlen sind also doppelt so hoch wie die eines einzelnen Kerns. Aber das hinterlässt uns immer noch eine beeindruckend hohe Bandbreite und niedrige Latenz.
Der L1D-Cache ist direkt in den CPU-Kern integriert und sehr eng mit den Ladeausführungseinheiten (und dem Speicherpuffer) gekoppelt . In ähnlicher Weise befindet sich der L1I-Cache direkt neben dem Teil des Kerns zum Abrufen/Dekodieren von Anweisungen. (Ich habe mir eigentlich keinen Sandybridge-Silizium-Grundriss angesehen, daher ist dies möglicherweise nicht buchstäblich wahr. Der Ausgabe- / Umbenennungsteil des Front-Ends liegt wahrscheinlich näher am "L0" -decodierten uop-Cache, der Strom spart und eine bessere Bandbreite hat als die Decoder.)
Aber mit L1-Cache, selbst wenn wir bei jedem Zyklus lesen könnten ...
Warum dort aufhören? Intel seit Sandybridge und AMD seit K8 können 2 Lasten pro Zyklus ausführen. Multi-Port-Caches und TLBs sind eine Sache.
David Kanters Beschreibung der Sandybridge-Mikroarchitektur enthält ein schönes Diagramm (das auch für Ihre IvyBridge-CPU gilt):
(Der "einheitliche Scheduler" hält ALU- und Speicher- vmovdqa ymm0, [rdi]
Uops , die darauf warten, dass ihre Eingaben bereit sind, und / oder auf ihren Ausführungsport warten. ( z Beispiel) .Intel plant uops an Ports zur Ausgabe-/Umbenennungszeit . 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 zum ROB und Scheduler hinzu Sie bleiben im ROB bis zum Ruhestand, aber im Scheduler nur bis zum Versand an einen Ausführungsport (dies ist die Terminologie von Intel; andere Leute verwenden Ausgabe und Versand anders)). AMD verwendet separate Scheduler für Integer / FP, aber Adressierungsmodi verwenden immer Integer-Registerrdi
add rdi,32
Wie dies zeigt, gibt es nur 2 AGU-Ports (Adresserzeugungseinheiten, die einen Adressierungsmodus annehmen [rdi + rdx*4 + 1024]
und eine lineare Adresse erzeugen). Es kann 2 Speicheroperationen pro Takt ausführen (mit jeweils 128 b / 16 Bytes), von denen einer ein Speicher ist.
Aber es hat einen Trick im Ärmel: SnB/IvB führen 256b AVX-Laden/Speichern als eine einzige uop aus, die 2 Zyklen in einem Lade-/Speicherport benötigt, aber nur die AGU im ersten Zyklus benötigt. Dadurch kann während dieses zweiten Zyklus ein Speicheradressen-Uop auf der AGU an Port 2/3 ausgeführt werden, ohne dass Lastdurchsatz verloren geht. Mit AVX (das Intel Pentium/Celeron-CPUs nicht unterstützen :/) kann SnB/IvB (theoretisch) 2 Lasten und 1 Speicherung pro Zyklus aufrechterhalten.
Ihre IvyBridge-CPU ist der Die-Shrink von Sandybridge (mit einigen mikroarchitektonischen Verbesserungen, wie mov-elimination , ERMSB (memcpy/memset) und Hardware-Vorabruf der nächsten Seite). Die Generation danach (Haswell) verdoppelte die L1D-Bandbreite pro Takt, indem die Datenpfade von den Ausführungseinheiten zu L1 von 128b auf 256b erweitert wurden, sodass AVX 256b-Lasten 2 pro Takt aufrechterhalten können. Außerdem wurde ein zusätzlicher Store-AGU-Port für einfache Adressierungsmodi hinzugefügt.
Der Spitzendurchsatz von Haswell/Skylake beträgt 96 geladene und gespeicherte Bytes pro Takt, aber das Optimierungshandbuch von Intel legt nahe, dass der anhaltende durchschnittliche Durchsatz von Skylake (immer noch unter der Annahme, dass keine L1D- oder TLB-Fehler ausfallen) ~81 B pro Zyklus beträgt. (Eine skalare ganzzahlige Schleife kann laut meinen Tests auf SKL 2 Ladevorgänge + 1 Speicher pro Takt aushalten und 7 Uops (unfused-domain) pro Takt von 4 Uops mit fusionierter Domain ausführen. Aber sie verlangsamt sich etwas mit 64-Bit-Operanden statt 32-Bit, also gibt es anscheinend ein Ressourcenlimit der Mikroarchitektur, und es geht nicht nur darum, Speicheradressen-Uops auf Port 2/3 zu planen und Zyklen von Lasten zu stehlen.)
Wie berechnen wir den Durchsatz eines Caches aus seinen Parametern?
Sie können nicht, es sei denn, die Parameter enthalten praktische Durchsatzzahlen. Wie oben erwähnt, kann selbst Skylakes L1D mit seinen Load/Store-Ausführungseinheiten für 256b-Vektoren nicht ganz mithalten. Obwohl es nah ist, und es kann für 32-Bit-Ganzzahlen. (Es wäre nicht sinnvoll, mehr Ladeeinheiten zu haben, als der Cache Leseports hatte, oder umgekehrt. Sie würden einfach 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 Takte ansehen, erhalten Sie nicht die ganze Geschichte. Die Bandbreite von L2 und L3 (und des Speichers) kann durch die Anzahl der ausstehenden Fehler begrenzt werden, die L1 oder L2 verfolgen können . Die Bandbreite darf Latenz * max_concurrency nicht überschreiten, und Chips mit höherer Latenz L3 (wie ein Xeon mit vielen Kernen) haben viel weniger Single-Core-L3-Bandbreite als eine Dual-/Quad-Core-CPU derselben Mikroarchitektur. Siehe den Abschnitt „latenzgebundene Plattformen“ dieser SO-Antwort . CPUs der Sandybridge-Familie verfügen über 10 Zeilenfüllpuffer, um L1D-Fehlschläge zu verfolgen (auch von NT-Speichern verwendet).
(Die aggregierte L3/Speicherbandbreite mit vielen aktiven Kernen ist auf einem großen Xeon enorm, aber Single-Thread-Code sieht eine schlechtere Bandbreite als auf einem Quad-Core bei gleicher Taktrate, da mehr Kerne mehr Stopps auf dem Ringbus und damit höher bedeuten Latenz L3.)
Wie wird eine solche Geschwindigkeit überhaupt erreicht?
Die Lastnutzungslatenz von 4 Zyklen des L1D-Cache ist beeindruckend, gilt aber nur für den Sonderfall des Pointer-Chasing (wenn es am wichtigsten ist) . In anderen Fällen sind es 5 Zyklen, was immer noch beeindruckend ist, wenn man bedenkt, dass es mit einem Adressierungsmodus wie beginnen [rsi + rdi * 4 + 32]
muss, also muss es eine Adressgenerierung durchführen, bevor es überhaupt eine virtuelle Adresse hat. Dann muss es das in physisch übersetzen, um die Cache-Tags auf Übereinstimmung zu überprüfen.
(Weitere Informationen zu dem Sonderfall, wenn die Registrierung von einem vorherigen Ladevorgang stammt, finden Sie unter Gibt es eine Strafe, wenn sich Basis + Offset auf einer anderen Seite als die Basis befindet? Intel scheint den TLB basierend auf der Adresse parallel zur Hinzufügung optimistisch zu untersuchen , und muss die uop im Ladeport wiederholen, wenn es nicht funktioniert.Großartig für Listen- / Baumknoten mit Zeigern früh im Knoten.[base + 0-2047]
base
base
Siehe auch Intels Optimierungshandbuch , Sandybridge Abschnitt 2.3.5.2 L1 DCache. Dies setzt auch keine Segmentüberschreibung und eine Segmentbasisadresse von voraus 0
, was normal ist; diese könnten es schlimmer als 5 Zyklen machen)
Der Ladeport muss auch den Speicherpuffer sondieren, um zu sehen, ob sich das Laden mit irgendwelchen früheren Speichern überschneidet. Und es muss dies selbst dann herausfinden, wenn eine frühere (in Programmreihenfolge) Speicheradressen-Uop noch nicht ausgeführt wurde, sodass die Speicheradresse nicht bekannt ist (in diesem Fall wird sie dynamisch vorhergesagt; falsche Vorhersagen verursachen Speicherreihenfolge-Pipeline-Nukes ). Aber vermutlich kann dies parallel zur Prüfung auf einen L1D-Treffer geschehen. Wenn sich herausstellt, dass die L1D-Daten nicht benötigt wurden, weil Store-Forwarding die Daten aus dem Speicherpuffer bereitstellen kann, dann ist das kein Verlust.
Intel verwendet VIPT-Caches (Virtually Indexed Physically Tagged) wie fast alle anderen, wobei der Standardtrick verwendet wird, den Cache klein genug und mit ausreichend hoher Assoziativität zu haben, damit er sich wie ein PIPT-Cache (kein Aliasing) mit der Geschwindigkeit von VIPT verhält (indizieren kann parallel zum TLB virtual->physical lookup).
Die L1-Caches von Intel sind 32 KB groß und 8-fach assoziativ. Die Seitengröße beträgt 4 KB. Dies bedeutet, dass die "Index"-Bits (die auswählen, welcher Satz von 8 Möglichkeiten eine bestimmte Zeile zwischenspeichern kann) alle unter dem Seitenversatz liegen; dh diese Adressbits sind der Offset in eine Seite und sind in der virtuellen und physikalischen Adresse immer gleich.
Weitere Einzelheiten dazu und andere Einzelheiten dazu, warum kleine/schnelle Caches nützlich/möglich sind (und in Kombination mit größeren, langsameren Caches gut funktionieren), finden Sie in meiner Antwort auf die Frage, warum L1D kleiner/schneller als L2 ist .
Kleine Caches können Dinge tun, die in größeren Caches zu leistungsintensiv wären, wie das Abrufen der Datenarrays aus einem Satz zur gleichen Zeit wie das Abrufen von Tags. Sobald also ein Komparator herausgefunden hat, welches Tag übereinstimmt, muss er nur eine der acht 64-Byte-Cache-Zeilen muxen, die bereits aus dem SRAM geholt wurden.
(Es ist nicht wirklich so einfach: Sandybridge / Ivybridge verwenden einen Banking-L1D-Cache mit acht Bänken mit 16-Byte-Blöcken. Sie können Cache-Bank-Konflikte bekommen, wenn zwei Zugriffe auf dieselbe Bank in verschiedenen Cache-Zeilen versuchen, im selben Zyklus ausgeführt zu werden. (Es gibt 8 Bänke, daher kann dies bei Adressen passieren, 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 64-B-Cache-Line-Grenze überschreitet. Ich denke, es findet anhand der niedrigen Adressbits heraus, welche Bank (en) abgerufen werden soll, und richtet die Verschiebung ein, die erforderlich ist, um die richtigen 1 bis 16 Datenbytes zu erhalten.
Bei Cache-Line-Splits ist es immer noch nur eine einzige uop, führt aber mehrere Cache-Zugriffe durch. Die Strafe ist immer noch gering, außer bei 4k-Splits. Skylake macht sogar 4k-Splits ziemlich billig, mit einer Latenz von etwa 11 Zyklen, genau wie ein normaler Cache-Line-Split mit einem komplexen Adressierungsmodus. Aber 4k-Split-Durchsatz ist deutlich schlechter als cl-Split Non-Split.
Quellen :
Bei modernen CPUs sitzt der Cache-Speicher direkt neben der CPU auf demselben Die (Chip) , er wird mit SRAM hergestellt, das viel, viel schneller ist als das DRAM , das 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 derselben Technologie wie die CPU selbst hergestellt wird, ist es genauso schnell wie die CPU. Außerdem müssen nur interne Busse (auf der CPU) verarbeitet werden. Wenn es sich also um einen 496 Zeilen breiten Bus handeln muss, ist dies wahrscheinlich der Fall.
L1-Caches sind ziemlich breite Speicherstrukturen. Die Architektur von 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 des atomaren Datenzugriffs.
Tabelle 2-17 (Abschnitt 2.3.5.1) zeigt, dass die Cache-Bandbreite beim Laden (Lesen) 2x16 = 32 Bytes pro Kern pro CYCLE beträgt . Dies allein ergibt eine theoretische Bandbreite von 96 Gb/s auf einem 3-GHz-Kern. Es ist nicht klar, was der zitierte Benchmark berichtet, es sieht so aus, als würde er zwei Kerne messen, die parallel arbeiten, also 192 Gbps für zwei Kerne machen.
Torverzögerungen sind was? 10 Pikosekunden? Zykluszeiten für ganze Pipeline-Operationen sind 333 Pikosekunden, mit verschiedenen Dekodierungs- und Busaktivitäten und Flip-Flop-Erfassung von Daten, bevor der nächste Taktzyklus beginnt.
Ich gehe davon aus, dass die langsamste Aktivität beim Lesen eines Cache darauf wartet, dass sich die Datenleitungen weit genug voneinander entfernen (wahrscheinlich sind diese differentiell: eine Referenz und eine tatsächliche Ladung vom Lesebit), dass ein Komparator/Latch getaktet werden kann, um ein positives zu implementieren. Feedback-Aktion, um eine winzige Spannung in einen großen Rail-to-Rail-Logikpegel-Spannungshub (etwa 1 Volt) umzuwandeln.
[reg + 0-2047]
) und eine TLB-Suche und einen Tag-Vergleich (8-Wege-Assoziativ) und das Setzen der resultierenden bis zu 16 nicht ausgerichteten Bytes auf die umfasst Ausgangsport der Ladeeinheit zur Weiterleitung an andere Ausführungseinheiten. Es ist eine Latenz von 4c für eine Pointer-Chasing-Schleife wie mov rax, [rax]
.
Benutzer16222
Ritter
user_1818839
Mathematiker
Rackandboneman
Peter Kordes
Rackandboneman
Peter Kordes
chrylis -vorsichtigoptimistisch-
Arthur
Oldtimer
Oldtimer
Peter Kordes
Oldtimer
Oldtimer
Peter Kordes
Peter Kordes
Oldtimer
Peter Kordes