Werbung
Zen/Zen+ war der erste große Schritt, der ein IPC-Plus von 52 % lieferte und AMD auf den aktuellen Weg brachte. Zen 2 war ein Zwischenschritt bei den Verbesserungen, die es nicht mehr in Zen/Zen+ geschafft hatten, aber dennoch einen deutlich größeren Leistungssprung ermöglicht haben, als man dies erwartet hatte. Plus 15 % IPC, eine Fertigung in 7 nm und damit verbunden ein Boost-Takt von bis zu 4,7 GHz waren die Früchte dieser Anstrengungen und aufgrund des bereits vielfach gelobten Chiplet-Designs sah sich AMD vor allem in Multi-Threaded-Anwendungen auf Augenhöhe mit Intel – inzwischen vielfach belegt durch unzählige Tests.
Während es zwischen Zen/Zen+ und Zen 2 noch viele Gemeinsamkeiten gibt, beschreibt AMD Zen 3 als erste vollständige Neuentwicklung nach der ersten Zen-Generation. Natürlich wirkt vieles auf den ersten Blick sehr ähnlich, schaut man jedoch tiefer auf die einzelnen Bestandteile, werden die vielen Detailverbesserungen und grundsätzlichen Änderungen deutlich. Zentraler Bestandteil ist ein neuer 8-Kern-Core-Complex (CCX), der sich einen gemeinsamen, 32 MB großen L3-Cache mit weiteren CCX-Ausbaustufen teilt. Es bleibt bei der Fertigung in 7 nm, wenngleich AMD beim Takt durch die Designänderungen und kleineren Verbesserungen in der Fertigung ebenfalls leicht zulegen kann.
Für Zen 3 gab es drei Designziele:
- Performance: Die 1T/IPC-Leistung soll einen deutlichen Sprung machen
- der 8-Kern-CCX soll Latenzen vereinheitlichen
- bei gleicher Leistungsaufnahme soll die Effizienz durch die ersten beiden Punkte gesteigert werden
Die Zen-3-Architektur in der Übersicht
In den kommenden Absätzen schauen wir uns die Zen-3-Architektur im Detail an.
Ein Zen-3-Kern kann weiterhin zwei Threads (SMT2) ausführen. Aller Anfang ist wie bei allen modernen Architekturen ein Branch Predictor, also die Sprungvorhersage. Eine Sprungvorhersage ist in aktuellen Architekturen unabdingbar, um die Pipelines der Recheneinheiten möglichst voll auszulasten. Ohne diese Maßnahme wären moderne Prozessoren deutlich langsamer. Sie sind aber auch Fluch und Segen zugleich, denn viele der Sicherheitslücken in Prozessoren sind darauf zurückzuführen, dass über Sprungvorhersagen Zugriffe auf Daten möglich sind, die eigentlich geschützt sein sollten.
Sowohl AMD als auch Intel arbeiten in immer ausgefeilteren Methoden der Sprungvorhersage. Im Grunde geht es darum, nach dem aktuellen Befehl schon den nächsten zu kennen, um diesen ebenfalls bereits auszuführen, bevor das Ergebnis des vorherigen Befehls bekannt ist. Über verschiedene Algorithmen ist es möglich, eine gewisse Wahrscheinlichkeit zu bestimmen, was dies für ein Befehl sein wird. Dies ist natürlich abhängig von der jeweiligen Anwendung. So kann die Hit-Rate, also die Treffergenauigkeit einer Sprungvorhersage, fast 98 % betragen, aber auch weit unter 50 % liegen. Dementsprechend unterschiedlich ist die Rechenleistung des Kerns in den verschiedenen Anwendungen.
Nicht nur die Genauigkeit spielt eine Rolle, auch die Anzahl der Sprungvorhersagen ist von Bedeutung. Mit der Zen-3-Architektur kann AMD mehr Sprungvorhersagen pro Taktzyklus machen. Bei einer fehlerhaften Sprungvorhersage muss an den vorherigen Status zurückgesprungen werden und auch diesen Prozess hat AMD hinsichtlich der Latenz beschleunigt.
Auf den Branch Predictor folgen zwei Wege, wie Befehle zum eigentlichen Kern gelangen. Es gibt einen 32 KB großen Instruction Cache (L1-Cache), der einen x86-Decoder mit vier Instruktionen pro Taktzyklus füttert. Dieser Instruktion Cache wurde optimiert und soll besser ausgelastet, bzw. ausgenutzt werden. Die Instruktionen werden in einer Op-Queue abgelegt. Tauchen Instruktionen immer wieder auf, können diese im Op-Cache abgelegt werden und mit acht sogenannten Macro-Ops pro Taktzyklus in die Op-Queue gelegt werden. Über den Dispatcher wird festgelegt, welche Instruktionen oder Macro-Ops in die Integer- oder Floating-Point-Pipeline übergeben werden. Bei Zen/Zen+ und Zen 2 hat AMD einige ineffiziente Prozesse identifiziert, die dazu Gefährt haben, dass der Dispatcher aus den zwei Pipelines (x86-Instruktionen und Op-Cache) nicht ideal zusammengeführt und in eine Ordnung gebracht wurde.
Es gibt weiterhin vier Integer-Einheiten mit acht Pipelines, die mit dedizierten Branch- und Store-Einheiten versehen wurden, so dass der Durchsatz an Integer-Rechenoperationen deutlich gesteigert werden konnte. Der Integer-Scheduler wurde von 92 auf 96 Einträge erweitert – aufgeteilt in 4x 24 AKU/AGU-Scheduler. Das dazugehörige Register File als Speicher wurde von 180 auf 192 Einträge aufgebohrt. Pro Taktzyklus können zehn anstatt sieben (4x ALUs, 3x AGUs, 1x Branch, 2x Store) Operationen durchgeführt werden.
Es bliebt bei vier ALUs und drei AGUs, allerdings teilen sich diese die Ressourcen mit Branch- und Store-Data-Units. Bei gleicher oder ähnlicher Anzahl an Recheneinheiten erhöht sich damit auch hier der Durchsatz. AMD balanciert die Integer-Einheiten an den Workloads, die auftreten, und erreicht damit eine höhere Effizienz. Dabei spielen auch die Shared Scheduler eine Rolle, die natürlich wissen müssen, welche Berechnungen sie parallel ausführen und bestmöglich aufteilen können.
Auf Seite der Floating-Point-Einheiten sind sechs Recheneinheiten vorgesehen. Man hat die einzelnen Einheiten (MUL, ADD, MAC, …) jedoch etwas breiter aufgeteilt, um diesen mehr Zeit zu geben und die Instruktionen besser verteilen zu können. So gibt es separate Einheiten für Stores und Floating Point Register File Moves. Hier soll es nun ebenfalls eine bessere Balance in den verschiedenen Einheiten geben, damit bestimmte Berechnungen mit einem höheren Durchsatz ablaufen können. Weiterhin ist Zen 3 in der Lage, zwei 256 Bit breite Multiply-Accumulate (FMAC) durchzuführen. Zen 2 benötigt für eine solche Berechnung fünf Taktzyklen, bei Zen 3 sind es nun nur noch vier.
In der Zen-2-Architektur konnten drei Speicheroperationen pro Taktzyklus ausgeführt werden – zwei Loads und ein Store. Mit Zen 3 sind es jetzt drei Loads sowie zwei Stores pro Taktzyklus, die zwar nicht gleichzeitig möglich sind, dennoch jeweils eine Steigerung von 33, bzw. 50 % ermöglichen, was dem Durchsatz ebenfalls zuträglich ist.
Darüber hinaus wurde die Store Queue von 48 auf 64 Einträge erweitert. Der L1-Data-Cache bleibt bei 32 kB (genau wie der L1-Instruction-Cache), kann jedoch dreimal mehr Speicher-Operationen pro Taktzyklus umsetzen. Aus den drei Load- und zwei Store-Einheiten kann pro Taktzyklus jeweils ein Datensatz übernommen werden – handelt es sich um 256 Bit große Datensätze (Floating Point) sind allerdings nur zwei Loads und ein Store möglich.
Zen 2 vs. Zen 3
In der Hierarchie einer Architektur beginnend sind die größten Unterschiede ein doppelt so großer Branch Target Buffer (BTB). Im Frontend ebenfalls verbessert wurden die Bandbreite der Sprungvorhersage und die Mobilität in den verschiedenen Schritten des Fronends, wozu eine schnellere Reaktion auf falsche Sprungvorhersagen gehört, aber auch der schnellere und präzisere Wechsel zwischen der x86- und Op-Cache-Pipeline.
Auf Seiten der ausführenden Recheneinheiten gibt es nun dedizierte Branch- und Store-Einheiten für die Integer-Pipeline, wo zuvor eine Branch-Einheit als Shared-Ressource nicht exklusive zur Verfügung stand. Dies soll den Durchsatz der Integer-Einheiten verbessern. Auch die Latenzen wurden hier verbessert. Für die Floating-Point-Operationen wurde die Anzahl der Pipelines von vier auf sechs aufgebohrt und die Berechnung von Floating Point Multiply-Accumulate (MAC) um einen Taktzyklus beschleunigt.
Die Steigerung von zwei Loads und einem Store auf drei Loads oder zwei Stores pro Taktzyklus erhöht im Speicherbereich den Durchsatz. Im Translation Lookaside Buffer (TLB) können nun sechs anstatt nur zwei Zeiger im Buffer nach den Einträgen suchen.