Details und Analyse der Zen-Architektur nach der Hot-Chips-Konferenz

Artikel-Index:

Die Decoder-Einheit im Detail

In der Deco­der-Ein­heit lan­den die 32 aus dem Befehls­cache gelie­fer­ten Bytes mit Pro­gramm­code im Inst­ruc­tion Byte Buf­fer. Aus die­sem selek­tiert ein Picker vier iden­ti­fi­zier­te x86-Befeh­le und lei­tet sie an die Deco­der-Ein­heit, wel­che die­se dann in ein inter­nes Befehls­for­mat (MOp) über­setzt und an einen MOp-Puf­fer schickt. Im Fal­le eines Tref­fers im MOp-Cache kön­nen von die­sem sogar bis zu 6 MOps in einem Takt­zy­klus an den Puf­fer gelie­fert wer­den, was auf Sky­lake-Niveau liegt. Beim Weg über die Deco­der liegt der Intel-Pro­zes­sor dage­gen mit bis zu 5 Befeh­len pro Takt leicht vorn. Nicht gezeigt ist der Weg der deco­dier­ten Befeh­le von der Deco­der-Ein­heit in den MOp-Cache. Falls im Pro­gramm­code ein nicht kor­rekt vor­her­ge­sag­ter Sprung statt­fin­det, ver­kürzt sich dank des Caches auch die soge­nann­te Branch Mis­pre­dic­tion Penal­ty, also die Dau­er bis zur Aus­füh­rung der kor­rek­ten ange­sprun­ge­nen Befeh­le. Der Cache spart hier meh­re­re Takt­zy­klen, was die Leis­tung stei­gert.

Aus dem MOp-Puf­fer (µOp-Queue)) her­aus wird für kom­ple­xe­re, nicht direkt in Hard­ware imple­men­tier­te Befeh­le die Aus­ga­be der dafür not­wen­di­gen Micro­code-Befeh­le aus dem Micro­code-Spei­cher (ROM) ange­sto­ßen. Zudem unter­sucht eine Stack Engi­ne den Code im Puf­fer auf Stack-Befeh­le, wel­che übli­cher­wei­se für die Zwi­schen­spei­che­rung von Wer­ten oder Über­ga­be von Para­me­tern ver­wen­det wer­den. Sind sol­che vor­han­den, kann die Engi­ne die Adres­sen dank typi­scher­wei­se ein­fa­cher Off­set-Adres­sie­rung (z.B. RSP+8) schon hier berech­nen. Das gab es auch schon in frü­he­ren Kern­ar­chi­tek­tu­ren, wie z.B. der Bull­do­zer-Linie. Da dien­te es aber nur dem Zweck, die Abhän­gig­kei­ten zwi­schen Stack-Befeh­len auf­zu­lö­sen, um die­se par­al­lel aus­füh­ren zu kön­nen. Die eigent­li­chen Stack-Spei­cher­zu­grif­fe muss­ten wei­ter­hin kom­plett aus­ge­führt wer­den, was Res­sour­cen beleg­te und Ener­gie ver­brauch­te.

Ein neu­er Ansatz hier ist nun, sich die Adres­sen von Stack-Schreib­zu­grif­fen (z.B. PUSH RAX) zu mer­ken und die­se Daten an spä­ter auf die glei­che Adres­sen zugrei­fen­den Lese­be­feh­len (z.B. ein dar­auf fol­gen­des POP RCX) direkt wei­ter­zu­lei­ten. Da nicht wei­ter auf das Mem­file ein­ge­gan­gen wur­de, gehen wir spe­ku­la­tiv davon aus, dass es wie ein klei­ner Stack Cache funk­tio­niert. Es könn­te dafür die Imme­dia­te-/Dis­pla­ce­ment-Ein­heit ver­wen­den, wel­che hier nicht expli­zit gezeigt wur­de, obgleich schon in der Bull­do­zer-Rei­he prä­sent. Dort legt das Front-End die bei x86-Befeh­len mit einem Kon­stan­ten­wert mit­ge­lie­fer­ten Wer­te ab und stellt die­se bei Befehls­aus­füh­rung ggf. bereit. Für die­se Zugrif­fe kann also auf die Nut­zung einer Address Genera­ti­on Unit (AGU) und der Load-/Sto­re-Ein­heit sowie des Level-1-Daten­caches ver­zich­tet und damit Ener­gie gespart wer­den. Frei­lich muss die Engi­ne noch über­wa­chen, ob irgend­wel­che ande­ren Spei­cher­zu­grif­fe sich mit den Stack-Zugrif­fen über­lap­pen, um Kon­flik­te zu ver­hin­dern und immer die kor­rek­ten Daten zu ver­wen­den.

Nach all die­sen Vor­ar­bei­ten kön­nen die ver­ar­bei­te­ten Befeh­le an den Dispatch-Puf­fer gesen­det und dort vor­ge­hal­ten wer­den. In die­sem Puf­fer wer­den die Befeh­le von der kom­pak­te­ren MOp-Form in ein­zel­ne µOps für die ver­schie­de­nen Funk­ti­ons­ein­hei­ten auf­ge­split­tet. Hier­bei kön­nen in einem Takt bis zu 6 µOps an die Inte­ger-Ein­heit sowie 4 µOps an die Fließ­kom­ma-Ein­heit gesen­det wer­den. Wie in der Fra­ge­run­de zu ver­neh­men war, wer­den zum Bei­spiel kom­ple­xe­re Ope­ra­tio­nen wie 256 bit brei­te AVX(2)-Befehle erst hier von einer MOp in 2 µOps auf­ge­teilt. Dies ist nötig, da AMDs FPU nur halb so breit ist. Genaue­res folgt dazu in der FPU-Beschrei­bung. Das spart Band­brei­te für MOps im Front End, wel­che dann für ande­re Befeh­le zur Ver­fü­gung steht. Somit kön­nen mehr Befeh­le aus dem Deco­der-Front-End in die Rechen­wer­ke des Back-Ends flie­ßen. Intels Mar­ke­ting­ab­tei­lung wür­de die­ses Fea­ture ver­mut­lich AVX-Fusi­on o.ä. nen­nen 😉

« Die Fetch-Ein­heit im Detail» Die Inte­ger-Ein­heit im Detail