AMD Ryzen 7 1800X Review – Teil 1

Artikel-Index:

AMD Ryzen – Die Architektur im Detail: Lade-/Speichereinheiten

Die Caches füt­tern natür­lich die Aus­füh­rungs­ein­hei­ten mit Daten. Bevor Letz­te­re aber in die Regis­ter gela­den oder geschrie­ben wer­den, müs­sen sie erst die Load-/Sto­re-Ein­hei­ten pas­sie­ren. Deren Auf­bau sehen wir auf dem nächs­ten Bild, unten mit­tig ist der 32 KiB gro­ße L1-Daten­cache positioniert:

Wie im gan­zen Kern üblich wird auch die­ser Vor­gang durch groß­zü­gi­ge War­te­schlan­gen abge­puf­fert, um Leer­läu­fe zu ver­mei­den und einen guten Durch­satz errei­chen zu kön­nen. In die­sem Fal­le gibt es eine Lade- und eine Spei­cher­war­te­schlan­ge. Ers­te­re ver­fügt über 72 War­te­plätz­te, letz­te­re über 44. Die Lade- und Spei­cher­schlan­ge sind über drei 128-Bit-Ports für zwei Lade- und eine Schrei­b­ope­ra­ti­on an den L1D-Cache ange­bun­den. Sowohl die Anzahl der War­te­plät­ze als auch die asym­me­tri­sche Auf­tei­lung liegt dar­in begrün­det, dass in den aller­meis­ten Fäl­len Rech­nun­gen nach dem Sche­ma A + B = C berech­net wer­den, wofür eben zwei Lade­vor­gän­ge plus ein Spei­cher­vor­gang nötig sind. Aus­nah­men kön­nen über Berech­nun­gen außer­halb der Befehls­rei­hen­fol­ge (OoO) und durch die vor­han­de­nen Puf­fer abge­fan­gen werden.

Flan­kiert wird die Spei­cher­ein­heit von einem bereits von Bull­do­zer bekann­ten Schreibe-&-Kombiniere-Puffer (Wri­te-Com­bi­ne-Buf­fer (WCB)), der Schrei­b­ope­ra­tio­nen zuerst sam­melt, zusam­men­fügt und erst dann schreibt, und dem MAB, einem Puf­fer für Speicheradressen.

Um die bereits gezeig­ten Res­sour­cen für Aus­füh­rung und Daten­hal­tung nicht ver­hun­gern zu las­sen, hat AMD auch das soge­nann­te Exe­cu­ti­on Front End, also die Befehls­ver­sor­gung, gegen­über Excava­tor ausgebaut.

Das beginnt mit in drei Ebe­nen vor­han­de­nen gro­ßen Adress­über­set­zungs-Spick­zet­teln (Trans­la­ti­on Loo­ka­s­i­de Buf­fers oder TLBs), die sowohl schnell als auch in die­ser Kom­bi­na­ti­on ener­gie­spa­rend sind. Dort wer­den ein­mal die Über­set­zun­gen von vir­tu­el­len in phy­si­ka­li­sche Adres­sen von Spei­cher­blö­cken mit Pro­gramm­code für den Schnell­zu­griff vor­ge­hal­ten. Treue Leser wer­den sich an die TLB-Pro­ble­me der ers­ten Bull­do­zer­ver­si­on und deren Ver­bes­se­run­gen ab Vis­he­ra erin­nern.

Eben­so erwäh­nens­wert ist der Hash Per­cep­tron Pre­dic­tor, also eine Sprung­vor­her­sa­ge-Ein­heit, die mit Hil­fe eines neu­ro­na­len Net­zes das Sprung­ver­hal­ten im aus­ge­führ­ten Pro­gramm­code lernt und vor­her­sagt. Das hat­ten auch schon die Cat-Ker­ne und spä­te­re Ker­ne der Bull­do­zer-Rei­he. Bei Zen wird gibt es jedoch die Neue­rung, dass das mit Hash­es ver­knüpft wird, um die Leis­tung noch zu stei­gern. Dabei bestimmt nicht allein die aktu­el­le Posi­ti­on im Pro­gramm­code, wel­ches Per­cep­tron zustän­dig ist, son­dern es wird aus der Adres­se und deren bis­he­ri­gen Sprung­his­to­rie ein Hash berech­net. Das erhöht die Tref­fer­quo­te nochmals.

Der 32 Ein­trä­ge gro­ße Return Stack Puf­fer ist wich­tig für die immer tie­fer ver­schach­tel­ten Auf­ru­fe heu­ti­ger Soft­ware und Betriebs­sys­te­me. Das Indi­rect Tar­get Array unter­stützt dage­gen z. B. bei vir­tu­el­len Funk­ti­ons­auf­ru­fen oder Sprung­ta­bel­len in Switch-Case-Anwei­sun­gen (für die Pro­gram­mie­rer unter uns).

Der mit 64 KiB (4‑wegig) aus­rei­chend dimen­sio­nier­te Level-1-Befehls­cache soll­te auch mit zwei Threads im SMT-Betrieb nicht so schnell Eng­päs­se auf­kom­men las­sen. Bei der Bull­do­zer-Rei­he, wo das Front End eben­falls zwei Threads abar­bei­ten konn­te, betrug die Grö­ße die­ses Cache anfangs auch 64 KiB (indes nur 2‑wegig), wel­che spä­ter auf 96 KiB (3 Wege) ab Steam­rol­ler auf­ge­stockt wur­den. Zudem gibt es bei Bull­do­zer im Zusam­men­spiel mit einem Linux-Sicher­heits­fea­ture (ASLR) Pro­ble­me, wo der im Cache lie­gen­de Pro­gramm­code bei bestimm­ten Kom­bi­na­tio­nen von Spei­cher­adres­sen zwei­er oder meh­re­rer Pro­gram­me gegen­sei­tig wie­der aus dem Cache gewor­fen wurde.

Nach­dem eine Adres­se ermit­telt und in die Phy­si­cal Request Queue für das Laden des nächs­ten Pro­gramm­codes aus dem Level-1-Befehls­cache ein­ge­reiht wur­de, wird par­al­lel über ein klei­nes Tag (µTag) geprüft, ob die gewünsch­ten Befeh­le schon im MOp-Cache vor­lie­gen. Lie­fert das µTag für den MOp-Cache kei­nen Tref­fer, wer­den die Befeh­le in einem 32 Byte-Block aus dem L1-Befehls­cache gela­den und an die Deco­der-Ein­heit weitergereicht.