- Im neuen BIOS für das ASRock B650 PG Lightning wurde der Loop Buffer von Zen 4 nicht mehr als Quelle für Mikro-Ops beobachtet; nach einem Downgrade auf ein älteres BIOS war er wieder aktiv
- Diese Struktur scheint dazu zu dienen, kleine Schleifen wiederholt im Frontend zu verarbeiten, um den Stromverbrauch zu senken, und wird auf 144 Einträge bei einem einzelnen Thread bzw. 72 Einträge pro Thread bei SMT mit 2 Threads geschätzt
- In SPEC CPU2017 liegt der Unterschied in der Gesamtwertung zwischen aktiviertem und deaktiviertem Loop Buffer bei unter 1 %, sodass die Auswirkungen auf die allgemeine Leistung sehr gering erscheinen
- Wenn der Loop Buffer deaktiviert ist, versorgt Zen 4 mehr Mikro-Ops aus dem Op Cache; dessen Bandbreite ist im Verhältnis zum Backend-Durchsatz groß genug, sodass kaum ein Frontend-Flaschenhals entsteht
- Der Grund für die Deaktivierung und die tatsächlichen Auswirkungen auf den Stromverbrauch sind unklar, aber da AMD diese eingeschränkte Funktion kaum dokumentiert oder beworben hat, dürften die meisten Nutzer und Entwickler die Änderung kaum bemerken
Rolle und Grenzen des Zen-4-Loop-Buffers
- Der Loop Buffer ist eine Struktur im CPU-Frontend, die einige bereits geholte Instruktionen speichert, damit beim wiederholten Ausführen kleiner Schleifen Teile des Frontends abgeschaltet werden können
- Das kann beim Stromsparen helfen
- Es bietet auch die Möglichkeit, die Grenzen des vorgelagerten Frontends zu umgehen und so die Leistung zu verbessern
- Diese Technik wird seit Langem in Intel-, Arm- und AMD-Kernen eingesetzt
- Zen 4 ist offenbar der einzige hochperformante AMD-Kern mit einem Loop Buffer
- Die Processor Programming Reference für Zen 4 erwähnt den Loop Buffer neben Op Cache und Decodern als Quelle für Mikro-Op-Dispatch
- Experimente mit Performance Countern deuten auf folgende Kapazität hin
- 144 Einträge bei Single-Thread-Ausführung
- 72 Einträge pro Thread bei aktivem SMT mit 2 Threads, statisch aufgeteilt
- Wenn sich CALL/RET innerhalb der Schleife befindet, kann der Zen-4-Loop-Buffer diese Schleife nicht erfassen
- AMDs Optimierungsleitfaden für Zen 4 behandelt den Loop Buffer nicht und rät nur dazu, Hot-Code-Bereiche innerhalb der Kapazität des Op Cache zu halten
Der Loop Buffer verschwindet nach einem BIOS-Update
- Nach dem Update des ASRock B650 PG Lightning auf BIOS 3.10 zeigte das Hardware-Performance-Monitoring, dass der Loop Buffer keine Mikro-Ops mehr dispatcht
- Nach dem Downgrade auf BIOS 1.21 war der Loop Buffer wieder aktiv
- Die Deaktivierung scheint zwischen AGESA 1.0.0.6 in BIOS 1.21 und AGESA 1.2.0.2a in BIOS 3.10 erfolgt zu sein
- AMD hat diese Änderung ohne gesonderte Ankündigung oder Vermarktung eingeführt
- Zusätzliche Gespräche mit AMD-Mitarbeitern auf der Hot Chips 2024 deuten darauf hin, dass der Loop Buffer in erster Linie der Stromoptimierung diente
Kleine Leistungsunterschiede in SPEC CPU2017
- Die Gesamtwertung der Integer- und Floating-Point-Suiten in SPEC CPU2017 unterscheidet sich zwischen aktiviertem und deaktiviertem Loop Buffer um weniger als 1 %
- Auch der SMT-Leistungsgewinn wird von der Deaktivierung des Loop Buffers nicht beeinflusst
- Der geringe Leistungseinfluss liegt wohl daran, dass der Op Cache von Zen 4 bereits mehr Bandbreite liefert, als die nachgelagerten Rename-/Allocate-Stufen verbrauchen können
- Selbst bei aktiviertem Loop Buffer zeigen Performance Counter, dass nur ein kleiner Teil der Mikro-Ops aus dem Loop Buffer kommt
- Auch in einzelnen Benchmarks wurden keine großen Einbußen festgestellt
- 523.xalanbmk nutzte einen nennenswerten kleinen Anteil des Instruction Streams aus dem Loop Buffer, doch die Werte lagen mit 9,48 im neuen und 9,44 im alten BIOS innerhalb der Messungenauigkeit
- 544.nab bezog fast ein Viertel seiner Mikro-Ops aus dem Loop Buffer, erreichte aber mit deaktiviertem Loop Buffer im neuen BIOS 11,7 statt 11,5 und damit 1,7 % mehr
- Dieser Anstieg kann auf Run-to-Run-Varianz zurückgehen
- In den Performance Countern des neuen BIOS übernimmt der Op Cache den Anteil des Loop Buffers und verarbeitet einen größeren Teil des Instruction Streams
- Bei 507.cactuBSSN sinkt die Op-Cache-Abdeckung teilweise, und die Decoder liefern etwa ein Viertel aller Mikro-Ops
- Performance Counter sind eher Werkzeuge zur Darstellung allgemeiner Trends als zu 100 % genaue Messinstrumente
- Frontend-Dispatch ist ein spekulatives Ereignis und kann auch von falsch geholten Instruktionen nach Fehlvorhersagen von Branches beeinflusst werden
Potenzielle Stromersparnis und Frontend-Aktivität
- Der Hauptzweck des Loop Buffers ist nicht die Leistungssteigerung, sondern das opportunistische Abschalten größerer Teile des Frontends einschließlich des Op Cache
- Die Performance-Monitoring-Funktionen von Zen 4 bieten eine Count Mask, mit der sich Zyklen zählen lassen, in denen ein Ereignis einen Schwellwert überschreitet
- Wird der Schwellwert auf 1 gesetzt, lässt sich abschätzen, in wie vielen Zyklen jede Mikro-Op-Quelle tatsächlich Mikro-Ops geliefert hat
- Damit kann eingeschätzt werden, wie oft sich das Frontend bei aktiviertem Loop Buffer abschalten lässt
- In SPEC CPU2017 passt die Aktivitätshäufigkeit jeder Quelle weitgehend gut zu dem Anteil der von ihr gelieferten Mikro-Ops
- In einigen Workloads gibt es auch viele Zyklen, in denen das Frontend gar nichts liefert
- 502.gcc und 520.omnetpp hängen stark an Backend-Speicherlatenzen
- Wenn die Out-of-Order-Engine nicht genügend Instruktionen in Flight halten kann, um Latenzen zu verstecken, kann das Frontend dem Backend nichts mehr schicken und bleibt untätig
- In der Floating-Point-Suite nutzen 544.nab und 508.namd den Loop Buffer über viele Core-Zyklen hinweg
- 508.namd ist mit durchschnittlich 3,64 IPC ein High-IPC-Workload und stellt hohe Anforderungen an den Frontend-Durchsatz
- Es ist Loop-Buffer-freundlich und bietet damit die Möglichkeit, den Op Cache abzuschalten und Strom zu sparen
- Ist der Loop Buffer deaktiviert, versorgt der Op Cache den Kern über mehr Zyklen hinweg
- Bei 523.xalanbmk muss der Op Cache ohne Loop Buffer zusätzlich in 12 % der Core-Zyklen aktiv sein
- 548.exchange2 ist mit durchschnittlich 4,31 IPC ebenfalls ein High-IPC-Workload, nutzt den Loop Buffer aber selbst bei Aktivierung kaum; der Op Cache ist in über 85 % der Core-Zyklen aktiv
- Bei 508.namd steigt der Aktivitätsanteil des Op Cache von 56,67 % mit aktivem Loop Buffer auf 75,1 % ohne ihn
- Ein Loop Buffer mit 144 Einträgen ist klein, um große Teile des Instruction Streams aufzunehmen
- Deutliche Effekte sind daher wohl nur zu erwarten, wenn ein Programm viel Laufzeit in kleinen Schleifen verbringt und weder durch Backend-Durchsatz noch durch Latenz begrenzt wird
Beobachtungen in Cyberpunk 2077
- Mit dem integrierten Benchmark von Cyberpunk 2077 wurde geprüft, wie sich die Deaktivierung des Loop Buffers auf die Spieleleistung auswirkt
- Um die Konsistenz zu erhöhen, wurde auf einem Ryzen 9 7950X3D Core Performance Boost deaktiviert und alle Kerne auf 4,2 GHz begrenzt
- Dabei wurde Bit 25 im Hardware-Configuration-Register MSR 0xC0010015 gesetzt
- Die RX 6900 XT wurde auf 2 GHz begrenzt
- Die Benchmark-Einstellungen waren 1080p, mittleres Preset, kein Upscaling
- Wenn das Spiel auf den VCache-Die festgelegt wurde, hatte die Deaktivierung des Loop Buffers nahezu keinen Einfluss auf die Leistung
- Auf den Non-VCache-Die festgelegt, wurde bei deaktiviertem Loop Buffer ein Leistungsverlust von 5 % beobachtet, dessen Ursache aber unklar bleibt
- Der Benchmark wurde etwa sechs Mal erneut ausgeführt
- Cyberpunk 2077 ist mit durchschnittlich etwa 22 % des Instruction Streams aus dem Loop Buffer loop-buffer-freundlicher als erwartet
- Nach der Deaktivierung des Loop Buffers stieg der Anteil der vom Op Cache gelieferten Mikro-Ops von 62 % auf 82 %
- Das Spiel ist mit durchschnittlich 0,89 IPC bei deaktiviertem und 1,02 IPC bei aktiviertem Loop Buffer kein High-IPC-Workload
- Frontend-Bandbreite ist also kein großes Thema
- Möglich ist eine Begrenzung durch das Backend oder durch Verzögerungen im Branch Predictor
- Beim Ausführen auf dem VCache-Die zeigen Performance Counter durchschnittlich 1,25 IPC mit aktivem und 1,07 IPC mit deaktiviertem Loop Buffer
- Auch mit dem neuen BIOS wurde ein kleiner Leistungsrückgang beobachtet
- Möglicherweise lag das System bei rund 155 FPS näher an einem GPU-Flaschenhals
Unsicherheit bei den Ergebnissen des Core-Power-Counters
- Um zu prüfen, ob die Ausführung über den Loop Buffer die Energieeffizienz verbessert, wurde auch der Core-Power-Counter von Zen 4 betrachtet
- Der Instruction-Bandwidth-Benchmark wurde so angepasst, dass im Testabschnitt kein CALL/RET verwendet wird
- Mit CALL/RET nutzt Zen 4 den Loop Buffer nämlich nicht
- Der Test wurde auf einen Kern festgelegt, und vor sowie nach dem Sprung zum Test-Array wurde der Core Energy Status MSR ausgelesen, um die durchschnittliche Leistungsaufnahme zu berechnen
- Core Performance Boost wurde deaktiviert, weil die Leistungswerte sonst stark schwankten
- Im alten BIOS zeigte der Core Energy Status MSR beim Holen von NOPs aus dem Op Cache durchschnittlich 6 W, beim Holen aus dem Loop Buffer jedoch eine deutlich geringere Leistungsaufnahme
- Selbst wenn die Größe des Test-Arrays auf 128 KB erhöht wurde, also passend in die L2-Kapazität und mit weniger als 1 % Op-Cache-Abdeckung, wurde die durchschnittliche Core-Leistung mit 1,5 W angegeben
- Das passt nicht zu einer Situation, in der Decoder und L2-Fetch-Pfad stärker genutzt werden sollten
- Im neuen BIOS ergab der Op-Cache-Test durchschnittlich 1,68 W, und auch ein Test, der die Decoder primär aus L2 speist, zeigte nahezu denselben Wert
- AMDs Power-Monitoring-Funktionen könnten eher auf Leistungsmodellierung als auf direkter Messung beruhen
- Zwischen den BIOS-Versionen könnte sich die Modellierungsmethode geändert haben, oder das Leistungsmodell passt nicht gut
- Ohne Hardware für Direktmessungen etwa am 12V-EPS-Anschluss war keine weitere Verifikation möglich
Gründe für die Deaktivierung und die Sicht der Entwickler
- Warum AMD den Zen-4-Loop-Buffer deaktiviert hat, ist nicht bekannt
- CPU-Funktionen werden mitunter wegen Hardware-Bugs deaktiviert
- Ein bekanntes Beispiel ist Intels LSD, der Loop Buffer von Skylake, der wegen eines Bugs im Zusammenhang mit Partial-Register-Zugriffen in kurzen Schleifen mit zwei aktiven SMT-Threads deaktiviert wurde
- Zen 4 ist AMDs erster Versuch, einen Loop Buffer in eine High-Performance-CPU einzubauen, und Erstimplementierungen sind schwer zu validieren
- Möglich ist, dass AMD intern einen extern nicht sichtbaren Bug gefunden und den Loop Buffer vorsorglich deaktiviert hat
- Die Auswirkungen auf die Leistung dürften minimal oder praktisch nicht vorhanden sein, weil die Bandbreite des Op Cache ausreicht
- Die Auswirkungen auf den Stromverbrauch sind unbekannt, könnten aber klein und schwer messbar sein
- AMD hat den Loop Buffer kaum dokumentiert oder beworben, abgesehen von einer einzelnen Zeile in der Processor Programming Reference
- Das steht im Kontrast zu Intel, das seinen eigenen Loop Buffer häufig dokumentiert und in Optimierungsleitfäden aktiv empfiehlt
- Der Zen-4-Loop-Buffer ist wegen seiner geringen Kapazität und der CALL/RET-Einschränkung eine begrenzte Funktion und nicht so nützlich wie der Op Cache
- Wer auf älteren BIOS-Versionen gezielt für den Zen-4-Loop-Buffer optimieren will, sollte folgende Bedingungen beachten
- Schleifen unter 144 Mikro-Ops halten
- Wenn sich zwei Threads einen physischen Kern teilen, nur etwa die Hälfte dieser Größe ansetzen
- Für in kleinen Schleifen aufgerufene Funktionen Inlining prüfen, um CALL/RET zu vermeiden
- Selbst mit solchen Optimierungen dürfte der Nutzen in den meisten Fällen ausbleiben
1 Kommentare
Meinungen auf Hacker News
Es liegt die Vermutung nahe, dass diese Funktion deaktiviert wurde, um eine bislang nicht veröffentlichte Hardware-Schwachstelle zu verhindern
Es ist nicht abwegig, sich vorzustellen, dass AMD intern einen Bug entdeckt hat, auf den zuvor niemand gestoßen war, und aus übertriebener Vorsicht den Loop Buffer abgeschaltet hat. Mir fällt kaum ein anderer Grund ein, warum AMD zu diesem Zeitpunkt im Lebenszyklus des Cores am Zen-4-Frontend herumschrauben sollte
Für mich riecht das nach einer Microcode-Mitigation, aber natürlich muss man auf eine CVE warten
Wenn die Schwachstelle nicht offengelegt wird, haben Betroffene außer reiner Paranoia keine Möglichkeit, mit Gegenmaßnahmen zu beginnen. Die Offenlegung einer Schwachstelle ist auch eine Art, die Verantwortung letztlich auf die Endnutzer abzuwälzen: Wer nicht aktualisiert hat, soll sich nicht beschweren. Dass eine Offenlegung zu Produkthaftung führt, ist selten, und ich erinnere mich nicht, dass es bei Meltdown oder Spectre solche Haftungsfragen gegeben hätte. Deshalb würde ich AMD nicht vorschnell unterstellen, das absichtlich zu verbergen
Der Artikel scheint anzudeuten, dass der Loop Buffer weder Performance- noch Energiegewinne bringt.
Dann könnte es sich um den klassischen Fall handeln: „Ein Engineering-Team hat monatelang ein glänzendes neues Feature gebaut, es brachte am Ende aber keinen realen Vorteil, und trotzdem hat jemand es veröffentlicht, um das Gesicht zu wahren.“ Auch in Softwareteams habe ich erlebt, dass man eine Codebasis neu schreiben wollte, um Legacy-Ballast loszuwerden und die Performance zu steigern, und am Ende hatte man mehr Codezeilen und schlechtere Performance. In beiden Fällen hätte man es nicht ausliefern sollen
Es fällt schwer zu glauben, dass AMDs Engineering-Team so prinzipienlos wäre, Fläche und Energie für eine wertlose Hardwarefunktion zu opfern; ich neige hier eher zu der Annahme, dass Chips ’n Cheese die Auswirkungen nicht messen konnte
Das ist sehr frustrierend, aber niemand will sich die Zeit für Voruntersuchungen nehmen. Ein neues Projekt durchzudrücken stellt die Führungsetage eher zufrieden und führt zu weniger Nachfragen
Der interessanteste Absatz im Artikel ist dieser: Die beste Sicht auf den Loop Buffer von Zen 4 ist, ihn als Zeichen dafür zu verstehen, dass AMDs Ingenieure über freie Kapazitäten verfügen, um etwas auszuprobieren.
Diesmal hat es vielleicht keine Ergebnisse gebracht, aber Ingenieure mit Funktionen von niedrigem Risiko und geringer Auswirkung experimentieren zu lassen, ist eine gute Methode, um Vertrauen aufzubauen. Ich hoffe, dass wir künftig mehr von diesem Vertrauen sehen werden
Zu der Stelle „Seltsamerweise sinkt die Gaming-Performance um 5 %, wenn man auf den non-VCache-Die fixiert und den Loop Buffer deaktiviert. Ich weiß nicht warum“: Mit feineren Messungen der Leistungsaufnahme ließe sich vielleicht beurteilen, ob es mit dem Thermal-/Power-Budget zusammenhängt.
Diese Funktion wirkt auch so, als sei sie zum Stromsparen gedacht
Die meisten Kerne von CCD0 meines non-X3D-Chips schaffen 5,6 bis 5,75 GHz, während die Kerne von CCD1 bei 5,4 bis 5,5 GHz enden. Zen-4-Chips mit V-Cache haben eine deutliche Taktstrafe, aber der Cache kompensiert das mehr als ausreichend. Man müsste sehen, ob auf CCD1 desselben Chips sowohl mit aktivierter als auch deaktivierter Funktion getestet wurde und ob versucht wurde, andere Änderungen wie Sicherheitsfixes zu isolieren; im Artikel räumt man selbst ein: „nein“. Um es sauber zu machen, müsste man in einem BIOS mit aktivierter Funktion einen Weg finden, nur diese Funktion abzuschalten, und auf demselben Chip beide Varianten testen. Selbst dann könnten andere Verzweigungsbedingungen die Ergebnisse verfälschen. Mit einem vollständigen Performance-Profil wäre die Genauigkeit höher, aber das können vermutlich nur AMD-Ingenieure
Offenbar war es zu klein, um einen echten Unterschied zu machen, und nur in sehr speziellen Situationen relevant. Hätte man es größer gemacht, wären die Implementierungskosten im Verhältnis zum Nutzen wohl zu hoch gewesen.
Trotzdem wird es in einigen Workloads leichte Regressionen geben, aber AMD hat seit der Veröffentlichung auch kleine Performance-Verbesserungen geliefert. Bei Zen 4 hätte man es einfach zu einer BIOS-Option machen sollen. Dass sie das offenbar nicht getan haben, deutet auf die Möglichkeit eines Bugs oder Sicherheitsproblems hin
Anekdotisch war einer der wenigen Unterschiede zwischen dem 68000 von 1979 und dem 68010 von 1982 der „Loop Mode“, also das Hinzufügen eines 6-Byte-Loop-Buffers.
Man ließ zwei CPUs um einen Taktzyklus versetzt laufen und injizierte in die zweite CPU einen wiederherstellbaren Interrupt. Wenn man aber eine CPU mit MMU, 32-Bit-Befehlssatz und 24-Bit-Adressbus wollte, war das offenbar trotzdem günstiger als die damaligen Alternativen. Das müssen wirklich wilde Zeiten gewesen sein.
In ein 18-Bit-Wort passen vier Befehle, und ein Opcode dekrementiert den Loop Counter und springt dann an den Anfang des Worts zurück. In solchen Fällen kann das deutlich schneller laufen.
Einer davon musste der Loop-Befehl (DBcc) sein, also musste der Loop-Body aus einem einzigen Befehl bestehen. Praktisch das Einzige, was dadurch wirklich schneller werden konnte, war in etwa ein nicht optimiertes memcpy.
Interessant ist, dass das beim Cortex-A15 eine zentrale Designfunktion ist. Ich frage mich, ob es für andere Chips Zahlen zur Wirkung gibt.
Bei Geräten mit längerer Design-Lebensdauer, etwa Konsolen, könnte man es zumindest als Optimierungsziel nutzen.
Der Sinn von RISC ist ja, dass das Holen und Dekodieren von Befehlen viel einfacher oder fast trivial ist.
Ich habe einen 7950X3D, als Upgrade von einem Skylake 6700K. Unbewusst scheine ich mich zu Chips hingezogen zu fühlen, bei denen der Hardware-Loop-Buffer per Software deaktiviert wurde.
Interessanter Artikel, aber ich weiß nicht, wie viel Fläche der Loop-Buffer auf dem Die einnimmt.
Falls er in künftigen Chips entfernt wird, frage ich mich, ob man den Platz für etwas Nützlicheres verwenden könnte, etwa einen größeren L2-Cache.
Theoretisch kann ein Loop-Buffer in engen Schleifen Strom sparen oder die Performance erhöhen. In der Praxis scheint er beides nicht zu schaffen, und AMD hat ihn in Zen 5 vollständig entfernt.
Wenn das stimmt, ist das plausibel, und die Flächenkosten bestehen im Wesentlichen nur aus zusätzlicher Steuerlogik. Der teuerste Teil dürfte wohl sein, die Schleife überhaupt zu erkennen, aber verglichen mit der Queue-Größe scheint das ziemlich klein zu sein.
Die Analyse im Abschnitt „Leistung“ scheint nicht durch die Anzahl der pro Sekunde ausgeführten Befehle geteilt zu haben.
Um den Nutzen dieses Loop-Buffers zu sehen, müsste man mit ziemlicher Sicherheit Energie pro Befehl betrachten, nicht Energie pro Sekunde, also Leistung in Watt.
Sogar die Reihenfolge und der RAM-Inhalt können alles verändern. Man könnte mit aktivierter und deaktivierter Funktion jeweils Hunderte Läufe machen und es bis zu einem gewissen Grad isolieren, aber das würde enorm viel Zeit kosten und wäre trotzdem nicht zu 100 % korrekt. Schon das Abschalten einer Funktion kann dazu führen, dass Code einen anderen Branch nimmt und sich die gesamte Anordnung ändert. Ich kenne dieses konkrete Problem nicht, habe aber Fälle gesehen, in denen sich nach dem Abschalten einer Funktion die Last von den Integer-Units auf FPU oder GPU verlagerte oder fünf Befehle verschwanden, dafür aber zwei neue hinzukamen.