Wie kann Cache so schnell sein?

Hier ist ein Screenshot eines Cache-Benchmarks:

Ergebnisse des AIDA64-Cache- und Speicher-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?

Haben Sie darüber nachgedacht, wie klein der L1,2,3-Cache ist und wo er sich physisch befindet? Tipp, Sie brauchen sich nicht um einen Busstandard zu kümmern, wenn Sie den gesamten Chip besitzen
Bedeutet das, dass es wirklich Schaltungen mit so breiten Bussen in einer CPU gibt?
Wenn es sich um einen On-Chip handelt, was denken Sie, was die Begrenzung der Busbreite sein könnte?
Es befindet sich physisch näher an dem Ort, an dem die Daten ausgeführt werden. Kürzere Entfernungen, die die Signale zurücklegen müssen, bedeuten kürzere Zeiten, in denen sie diese Entfernung zurücklegen. Der Cache befindet sich auf der CPU und nicht auf dem Motherboard, sodass der Motherboard-Bus irrelevant ist.
Außerdem: Weiß der Benchmark genug darüber, was er tut, um sicherzustellen, dass einige Daten, mit denen er testet, nicht direkt in einem Register aufbewahrt werden?
@rackandboneman: AIDA64 ist ein angesehener Benchmark, nicht etwas, das jemand einfach in C gehackt hat und den Compiler einige Lasten optimieren lässt! Ich würde davon ausgehen, dass die Mikrobenchmark-Teile in Assembler mit SSE- oder AVX-Versionen geschrieben wurden.
@ Peter Cordes befriedigende Antwort - auf eine notwendige Frage.
@rackandboneman: Ja, einverstanden. Am Ende habe ich auch meine eigene Antwort auf die Fragen des OP gepostet.
Sie sprechen von einem "theoretischen Maximum", aber der springende Punkt beim CPU -Cache ist, dass es sich um eine physikalisch andere Art von Hardware handelt, mit einem eigenen Transistortyp, einer anderen Verbindungsarchitektur und Datenraten.
Nur um die Gedanken in die physikalische Perspektive zu rücken: In 1,4 Nanosekunden legt Licht etwa anderthalb Fuß zurück. Das bedeutet, wenn sich der Cache auf der anderen Seite des Motherboards befindet, könnte eine solche Latenz die Relativitätstheorie brechen. Oder ein Messfehler sein .
Bits pro Sekunde, diese Zahl macht absolut Sinn, L1 läuft mit der Geschwindigkeit der CPU, 64 Bits breite 3 GHz wären genau dort, fast genau die erwartete Geschwindigkeit, aber wenn das Bytes pro Sekunde sind, macht das überhaupt keinen Sinn ...
Es heißt auch, der FSB ist 100 MHz, was ist das Ende der 1990er Jahre?
@old_timer: Moderne CPUs lachen über Ihre mickrige Vorstellung, nur ein Maschinenwort pro Takt aus dem L1D-Cache zu laden. Haben Sie noch nie von SIMD-Vektoren gehört? Betreff: FSB: Es gibt überhaupt keinen FSB (der Speichercontroller ist integriert; die Kommunikation zwischen CPU und Southbridge erfolgt über DMI , was PCIe sehr ähnlich ist). Die "FSB-Uhr" ist nur ein Name für die Basisuhr. Die CPU betreibt ihre Kerne mit einem Multiplikator dieses Takts (z. B. 34x). Siehe thinkcomputers.org/intel-ivy-bridge-overclocking-guide . Auch PCIe-Takte skalieren damit.
Wenn der Cache sicher mehrere Ports hat und oder wenn der Bus 512 Bit breit ist, sicher ... aber wenn nicht, können Sie nicht so viel daraus machen, elementares digitales Design, hat nichts mit der Art des Befehlsbefehlssatzes usw. zu tun Vor ein paar Jahren war FSB 800 MHz und jetzt sind es 100? Es ist nur eine Terminologiesache. Der Ref-Takt ist im Allgemeinen 100 MHz und das ist gut verständlich, aber die Definition des Begriffs in die schlechte Richtung zu wechseln, sieht einfach schlecht aus. und ja, mit Sandybridge oder vielleicht kurz davor haben sie das, was früher außerhalb des Chips war, hineingezogen, wodurch dieser Bus entfernt wurde. gut verstanden.
@PeterCordes Sie müssen auf Chipebene denken, nicht auf einer magischen hohen Ebene, Transistoren sind Transistoren, Sram-Blöcke sind Sram-Blöcke. Die Technologie verwendet unterschiedliche Materialien und kann Dinge kleiner machen, aber digital können Sie in einem Taktzyklus nicht auf magische Weise 8 verschiedene Bits über dieselbe Spur in der Metallschicht lesen. SIMD kann das nicht bewirken, und auch nichts anderes als 8 Taktzyklen mehr pro Bit oder 8 Spuren und 8 Bit. Und das kann sehr gut sein, was vor sich geht, und / oder wie bei den meisten Benchmarks sind sie BS, trivial abzustimmen, um ein Ergebnis anzuzeigen, oder irgendwo dazwischen.
@old_timer: Mein Punkt war, ja, SIMD-Ladeports sind breiter als 64 Bit, weil das eine nützliche Sache ist, um Transistoren / Die-Fläche / Drähte auszugeben. (Und ja, Intels L1D-Cache ist auch multiportfähig). Siehe meine Antwort für ein Blockdiagramm. (Einverstanden, dass "FSB-Uhr" ein dummer Name ist. Technisch heißt es BCLK, und die meisten Leute, die wissen, wovon sie sprechen, nennen es so. Ich habe als beschreibender Linguist gehandelt und beschrieben, wie der Begriff (meiner Meinung nach falsch) verwendet wird von einigen Übertaktern.)
@old_timer: Vermutlich funktioniert die GUI von AIDA64 immer noch auf Systemen, die wirklich einen FSB haben, und sie haben sich entschieden, nicht zwei verschiedene Sätze von Layouts / Labels auf der GUI zu haben.
@PeterCordes Natürlich verwendet Intel weiterhin Namen wie i3, i7, Pentium usw., um vielleicht Verwirrung zu stiften, oder wer weiß ... Und dies wird als Cache-Leistungstest bezeichnet, der so darauf abgestimmt ist, eindeutig 497 oder realistischer 512 Bit pro Zyklus können sie aus L1 herausziehen (kontinuierlich könnten 1024 oder 2048 oder andere Bits möglich sein, können dies aber im Durchschnitt pro Takt nicht aufrechterhalten). Interessante Zahlen, aber für den realen Gebrauch (wie bei jedem Benchmark) müssen sie abgewertet werden.
@old_timer: Es sind tatsächlich 2x 128 Bit pro Takt pro Kern auf IvB. In einem Schnelltest mit Leistungszählern für Kerntaktzyklen auf Skylake habe ich 1,9990 Lasten von 256b pro Kerntakt in einer kleinen Schleife gemessen. Insbesondere 4001,949414 Millionen Kerntakte für ein ganzes Programm, das 8000 Millionen Ladevorgänge ausgeführt hat. Kein L1D-Cache fehlt, weil ich wiederholt von denselben 2 Zeilen neu geladen habe, aber ich habe es in asm geschrieben, damit nichts in der Software wegoptimiert wird. Auch in weniger synthetischen Fällen können Sie der theoretischen L1D-Spitzenbandbreite auf Intel-CPUs oft sehr nahe kommen, wenn Sie andere Engpässe vermeiden.

Antworten (5)

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.

Auf Seite 55 des Dokuments @next-hack wird darauf verwiesen: "Intern sind Zugriffe bis zu 16 Bytes. [...] Zwei Ladevorgänge und ein Speichervorgang können in jedem Zyklus ausgeführt werden". Das erklärt, warum das Lesen doppelt so schnell ist – es kann zwei Lesevorgänge im selben Vorgang ausführen und gleichzeitig einen Schreibvorgang ausführen.
Ja, im Grunde wissen die Intel-Ingenieure, was sie tun. Es schneller zu machen, wäre eine Verschwendung von Ressourcen ...
Ja, es zählt eindeutig Copy BW = Lesen und Schreiben. Das scheint genauso gültig wie die Alternative, da es wichtig ist, dass die Lese- und Schreibvorgänge parallel ausgeführt werden können. Beachten Sie, dass die OP-Nummern für L2/L3 nicht viel höher als schreiben und niedriger für den Speicher sind. Der DDR3-Speicherbus ist nicht vollduplex: Zum Lesen und Schreiben werden dieselben Datenleitungen benötigt. (Weitere Informationen zur x86-memcpy/memset-Bandbreite mit NT-Speichern im Vergleich zu regulären Speichern finden Sie unter stackoverflow.com/questions/43343231/… ).
Sie vermuten, dass IvyBridge 2 Lese- und 1 Schreibvorgänge im selben Taktzyklus ausführen kann. Sie haben zufällig Recht, aber nur unter sehr begrenzten Umständen. IvB hat nur 2 AGU -Ports, daher ist es normalerweise auf 2 Speicheroperationen pro Takt begrenzt, von denen bis zu einer ein Speicher sein kann . Aber 256b-AVX-Ladevorgänge/Speichervorgänge benötigen 2 Zyklen, um in den Lade-/Speicherports ausgeführt zu werden, während nur die AGU im ersten Zyklus benötigt wird. So kann ein Store-Adress-Uop während dieses zweiten Zyklus einer 256b-Last auf Port 2/3 laufen, ohne Ladebandbreite zu kosten. (Store-Data-UOPs laufen auf Port 4.) Quelle: agner.org/optimize microarch pdf
Eine AMD Bulldozer-Familie oder eine Ryzen-CPU würde Ihnen die gleichen Lese- = 2x Schreibzahlen geben, aber sie sind wirklich auf 2 Speicheroperationen pro Takt (bis zu einer kann ein Schreibvorgang sein) ohne Schlupflöcher begrenzt. Lesen/Schreiben/Kopieren erkennt den Unterschied nicht, aber Triad kann ( 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/5
Ich habe eine Antwort geschrieben , da ich niemanden gesehen habe, der über L1D-Latenz gesprochen hat, nur über Bandbreite.
@PeterCordes, "Ich habe niemanden gesehen, der über L1D-Latenz gesprochen hat" ... Hmm ... Vielleicht, weil niemand gefragt hat?
@AliChen: Das OP erwähnte ausdrücklich die 4-Zyklen-Lastnutzungslatenz von IvyBridge direkt nach der Bandbreite, bevor es fragte, wie es so schnell sein kann.

Die 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-Registerrdiadd rdi,32

SnB-Speicherdiagramm von David Kanter

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


Cache-Latenz

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]basebase

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 :

Das ist sehr klar, erschöpfend und gut geschrieben! +1!

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.

Danke für Ihr Interesse. Ich habe in einigen Büchern gesehen, dass die Registerzugriffsgeschwindigkeiten über 300 GB/s liegen. In diesem Fall beträgt der Registerdurchsatz für einen 3-GHz-Prozessor 100 B/Zyklus, was nicht möglich ist, da Register normalerweise 64/128 Bit breit sind. Sie konnten nicht so viel ausgeben. Das ist es, was mich beschäftigt. Ist GB/sa der richtige Weg, um den Durchsatz auszudrücken?
@Knight Denken Sie daran, dass IvB (wie jeder Hochleistungsprozessor) mehrere Anweisungen pro Zyklus ausführt, z. B. 3 ALU-Operationen, 2 Ladevorgänge und 1 Speicher. Die meisten davon können 2 Eingänge aufnehmen (gerade Lasten, für indizierte Adressierung) und die Last nimmt sogar 3. Das sind 13 Register zu je 8 Bytes, 104 Bytes (es könnte der Fall gewesen sein, dass eine solche epische Kombination nicht erlaubt ist, aber da ist kein Hinweis darauf, dass dies für IvB der Fall ist, obwohl es nicht aufrechterhalten werden kann). Wenn Sie auch Vektorregister berücksichtigen, steigt diese Zahl noch weiter an.
@harold: verwandt: Haswell und Skylake scheinen Beschränkungen für Registerlesevorgänge pro Takt zu haben, obwohl dies möglicherweise im Front-End liegt und einen Ausführungsstoß nicht beeinflusst, nachdem einige Eingaben bereit sind. Vielleicht ist es eine andere mikroarchitektonische Grenze, aber ich habe Engpässe im Code gefunden, die in der Lage sein sollten, mehr Operationen pro Takt aufrechtzuerhalten. agner.org/optimize/blog/read.php?i=415#852 . Auf Haswell las mein Best-Case-Szenario ~ 6,5 ganzzahlige Register pro Taktzyklus (anhaltend). Ich habe es auch geschafft, 7 Uops pro Uhr auf Skylake zu versenden/auszuführen (Geschäfte sind Geschäftsadresse + Geschäftsdaten).
@PeterCordes das muss aber das Frontend sein, oder? IIRC, das war auch historisch das Problem (PPro zu Core2), und ich bin mir nicht sicher, wie Bruchzahlen sonst Sinn machen. Obwohl meine Zahlen sowieso ein bisschen daneben lagen
@harold: Ja, ich bin mir ziemlich sicher, dass es sich um eine Art Front-End-Engpass handelt, wahrscheinlich bei der Umbenennung. Der Register-Lese-Engpass von P6 lag bei "kalten" Registern, die aus der permanenten Registerdatei in das fragliche ROB gelesen werden mussten. Kürzlich geänderte Register befanden sich noch im ROB, und es gab keinen Engpass. Ich habe nicht viel mit Cold vs. Hot Regs auf HSW/SKL untersucht, da ich aus irgendeinem Grund nicht daran gedacht habe, meinen Loop größer als 4 uops / idealerweise 1c pro Iteration zu machen. Hoppla. IDK, wie groß der Unterschied zwischen Weiterleitung und PRF-Lesevorgängen ist (die zur Ausführungszeit erfolgen müssen, nicht zur Ausgabe/Umbenennung).
@Knight: Ihre CPU hat AVX deaktiviert, aber auf IvyBridge mit AVX sind die Register 256b breit. Viele Vektorbefehle lesen zwei und schreiben 1, und IvB kann 3 Vektor-ALU-Befehle pro Takt ausführen. (3 GHz * 3 * 32 B = 288 GB/s). (Die 4. Insn pro Takt könnte eine Reg-Reg-Verschiebung sein, die durch Umbenennen eliminiert wird, oder ein 256-Laden oder -Speichern bei jedem zweiten Takt). Sie könnten dies in GB/s messen, aber das ist albern. An diesem Punkt sollten Sie uops pro Takt zählen und im Allgemeinen versuchen, die Anzahl der uop / Anweisungen bei der Optimierung zu minimieren. Durch das Zählen von GB/s sieht ein Integer-Befehl "schlechter" aus als ein Vektor-Insn.

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.

Denken Sie daran, dass die 4-Zyklen-L1D-Latenz die Adressgenerierung (für einfache Adressierungsmodi von [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].