A processzorok mélylélektana

Utasítás-végrehajtás

Processzor megnevezéseAMD K7AMD K8AMD K10Intel MeromIntel Penryn
Futószalag hossza (lépcső)10/15 (int/fp)12/17 (int/fp)14
ElágazásbecslésBTB: 2048 bejegyzés;
GHBC: 2048 bejegyzés;
RAS: 12 bejegyzés
BTB: 2048 bejegyzés;
GHBC: 16384 bejegyzés;
RAS: 12 bejegyzés
BTB: 2048 bejegyzés;
GHBC: 16384 bejegyzés;
RAS: 24 bejegyzés;
indirekt előrejelző: 512 bejegyzés
BTB: ? bejegyzés;
?
RAS (Intelnél RSB): 16 bejegyzés
Behívó (fetch) szélessége16 bájt32 bájt16 bájt
x86 dekódolók száma1 egyszerű + 1 komplex
64 bit széles
1 egyszerű + 1 komplex
128 bit széles
1 komplex + 3 egyszerű
x86 dekódolók sebessége/órajel (AMD: macro-op;
Intel: micro-op)
34+1
ROB mérete72 bejegyzés96 bejegyzés
ROB kimeneteinek száma6 (3 Int/3 FP [ebből 2 SSE is])6 (3 Int/3 FP [ebből 2 SSE is+FSTORE mov])8 (3 Int/2 FP/3 SSE)
Ütemezés módja54 férőhelyes (18 Int/Mem, 3x12 FP [64 bit]) RS60 férőhelyes (3x8 Int/Mem, 3x12 FP [64 bit]) RS60 férőhelyes (3x8 Int/Mem, 3x12 FP [128 bit]) RS32 férőhelyes RS (vegyes)
Integer végrehajtók száma3 teljes értékű ALU3 teljes értékű ALU + 1 ABM1 teljes értékű ALU + ALU branch + ALU Shift/Rotate
FP végrehajtók számaFADD + FMUL + FSTOREFADD + FMUL + FSTORE (SSE mov)FADD + FMUL/FDIV + FSTORE + FLOAD
Órajelenkénti INT SIMD műveletek száma1 x 64 bit2 x 64 bit2 x 128 bit (+FSTORE SSE mov)3 x 128 bit
Órajelenkénti FP SIMD műveletek száma1 x 64 bit2 x 64 bit2 x 128 bit3 x 128 bit

A harmadik fejezetben a processzorok magjával, az utasításfeldolgozással foglalkozunk, ez talán a legizgalmasabb és egyben legtrükkösebb téma az összes közül. A különböző architektúrák egyes jellemzőivel nagyjából tisztában kell lenni, hogy megértsük a miérteket. Az AMD oldaláról kezdve megint a sort, a K10 gyakorlatilag még mindig a 8 éves K7 kétszeresen továbbfejlesztett változatának tekinthető. A már kitárgyalt cache-szervezésen és memória-kezelésen felül sok minden megváltozott, de igazán gyökeresen semmi sem. A futószalag hosszabb lett, hogy a K8, majd a K10 magasabb órajelet tudjon elérni. Az elágazásbecslés javult, a fetch szélessége viszont csak a K10-ben szélesedett ki duplájára, igaz, a K7/K8 esetében nem is volt szükség 16 bájtnál többre, hiszen az előző két generáció nem tudta olyan gyorsan feldolgozni az utasításokat. Az x86 dekódolók a K10 megjelenéséig változatlanok voltak: kettő van belőlük, az egyszerű utasításokat feldolgozó DirectPath és a komplex utasításokat feldolgozó VectorPath, mindkét egység órajelenként maximum három utasítás dekódolására képes, viszont a K10 dekódolói a 128 bites SSE utasításokat is egy órajel alatt dekódolják, ami kétszeres sebesség a K8-hoz képest. A ROB mérete a K7 óta nem változott, és a kimeneti portok száma sem, három egész és három lebegőpontos dispatch port van. A reservation station szélessége a K7–K8 váltásnál szélesedett az integer oldalon, a végrehajtó egységeknél a K10 kapott egy ABM egységet, a lebegőpontos/SSE-végrehajtók pedig 128 bitre szélesedtek, így SSE-végrehajtásban a K10 itt is dupla olyan gyors, mint a K8, sőt, picit gyorsabb, mert az FSTORE ág is képes a 128 bites MOV parancsot végrehajtani, igaz, picit nagyobb késleltetéssel, mint kellene.

Hirdetés

A Core architektúra is egy sok éves design továbbfejlesztése, a Pentium M-ből alakult ki, amely a Pentium Pro leszármazottja (1995). A Core architektúra a wide, azaz széles utasításvégrehajtás jegyében született, erre utal egy komplex plusz három egyszerű x86 dekódolója, a macro-op fusion, mellyel CMP és JUMP utasításokat lehet egybeforrasztani, a micro-op fusion, mellyel a már dekódolt utasításokat lehet egybeolvasztani, a széles ROB, a nyolc végrehajtóegység (hat porton), a három 128 bites SSE-végrehajtó és az ezektől elkülönített három AGU is.

Hogy a különbségekre fény derüljön, ismét az Everest tesztjeit vettük elő, 2 GHz-en mértük le a processzorokat, 10x200 MHz-es CPU-órajel és DDR2-800-as beállítás mellett. Hogy az egyes eredmények hátterét megértsük, felvettük a kapcsolatot a program készítőivel.

A CPU Queen egy egyszerű, egész számokkal dolgozó benchmark, amely a processzorok elágazásbecslési képességeire fókuszál, és a „nyolc királynő egy sakktáblán” feladványra épül (10 x 10-es sakktáblán). A teszt MMX-, SSE2- és SSSE3-optimalizált, és kevesebb mint 1 MB memóriát foglal le. Ebben a tesztben az elágazáskezelés képességei határozzák meg a pontszámot. Nemcsak a branch prediction táblák és a becslés pontossága, a return stack mérete, hanem az is, hogy az utasításkészlet támogatja-e valamilyen módon maguknak az elágazásoknak az elkerülését (van-e CMOV vagy PABSB utasítás), illetve képes-e egyszerre párhuzamosan több bábu helyzetével számolni. Mint látható, a K7–K8–K10 generációváltások itt mindig gyorsulást hoztak magukkal (lásd fentebb a táblázatot is), de a K10 nem elég erős ahhoz, hogy befogja a Core-t (az SSSE3 is sokat nyom a latba).

A CPU Photoworxx különböző digitális fotófeldolgozási műveleteket hajtat végre a processzorral (kitöltés, forgatás, random stb.). Ez a teszt főleg a processzorok integer számolási végrehajtási egységeit dolgoztatja meg a memória-alrendszerrel egyetemben, ezért nem skálázódik olyan jól több processzormag esetén. A teszt csak alap x86-os utasításokat használ. Photoworxx a legösszetettebb teszt, többféle méretű képpel dolgozik, sok minden számít benne, de leginkább az átlagos memóriaelérés ideje a döntő. Sokat jelentenek a jobb prefetcherek, és itt számít a legtöbbet a memória és a cache-ek hatása. A K7 ennek eredményeképpen szépen le is maradt, egy szálon tesztelve pedig a K8–K10 váltás sem hozott túl sok gyorsulást. A Core processzorok itt nem annyira gyorsak a rendszerbusz miatt.

A CPU ZLib is egy integer benchmark, amely a publikusan elérhető ZLib fájltömörítési algoritmussal méri le a processzor és a memória-alrendszer teljesítményét, ez a teszt is csak alap x86-os utasításokat használ. Itt inkább a CPU sebessége, illetve képességei számítanak (dekódolás szélessége, out-of-order load támogatása, ugrásbecslés, reordering ablak mérete), mint a memória sebessége. A K10 LSU-ja már támogat egyfajta OoO-végrehajtás, ennek eredményeképpen jóval gyorsabb, mint a K8.

A CPU AES is egy integer benchmark, amely az AES (azaz Rijndael) adattitkosító algoritmust használja. A teszt Vincent Rijmen, Antoon Bosselaers és Paulo Barreto publikusan elérhető C kódját használja ECB módban. A benchmark alap x86-os utasításokat, és összesen 48 MB memóriát használ. Itt is inkább a CPU sebessége a fontos, illetve kiugróan az out-of-order load képesség számít (a hardveres AES támogatást leszámítva persze). A K10-ben debütáló OoO-memóriavezérlés itt is érezteti hatását, de a Core gyorsabb volt.

Az FPU Julia a processzorok 32 bites (egyszeres pontosságú) lebegőpontos teljesítményét méri le a „Julia” fraktál segítségével. A benchmark kódja assemblyben íródott, és extrém mértékben használja ki az egyes AMD és Intel SIMD-utasításkészleteket (x87, 3DNow!, 3DNow!+, SSE). A teszteredmények okán sokat töprengtünk, ugyanis nem értettük, hogy miként lehet ennyivel gyorsabb a Core. Végül már majdnem arra a következtetésre jutottunk, hogy a gyorsabb SSE-végrehajtás miatt, de végül a program készítői adták meg a magyarázatot. A Julia bench beleszalad a K8/K10-nek abba a korlátjába, hogy az architektúra nem bírja, ha cserélődnek az SSE regisztereknél az adattípusok. A Core-on ez nem gond, és emiatt gyorsabb/rövidebb kódot lehet írni.

Az FPU Mandel a 64 bites (kétszeres pontosságú) lebegőpontos teljesítményt méri le a „Mandelbrot” fraktál egyes frame-jeinek kiszámolása révén. Ez a benchmark is assemblyben íródott, és hasonlóan az FPU Juliához, kihasználja az egyes SIMD-utasításkészleteket (x87 vagy SSE2). Ebben a tesztben szépen meglátszik, hogy az SSE-végrehajtók szélessége megduplázódott, de a Core 3 x 128 bites ütemét a K10 sem képes befogni, annak ellenére, hogy a K10-ben az FStore ág is képes a MOVAPx reg, reg végrehajtására. A Julia benchez képest a K10 itt azért szerepel jól (pontosabban fogalmazva nem vérzik el úgy, mint a Juliában), mert a Julia belső ciklusa egyszerre 8 pixelen dolgozik, a Mandelé viszont csak 4 pixelen, emiatt a típusváltást (int/float) kiváltó kód Mandelban rövidebb és gyorsabb az AMD CPU-kon.

Az FPU SinJulia a 80 bites (kiterjesztett pontosságú) lebegőpontos teljesítményt méri le a „Julia” fraktál módosított változatának kiszámolásával. A kód assemblyben íródott, és erősen kihasználja a trigonometrikus és exponenciális x87-es utasításokat. Míg a Juliánál a raw 32 bites lebegőpontos MUL/ADD/MOV képességek számítanak, addig a SinJuliánál a legpontosabb 80 bites mód kihajtása a lényeg, és a transzcendens utasítások (sin, cos, ex) megvalósítása. Teljes végrehajtási idő szempontjábol a sin, cos, ex sebessége a döntő, amiben egyébként a P6 leszármazottai hagyományosan gyorsabbak.

Külön a SIMD utasításkészletekre koncentrálva elővettük a TMPGEnc XP 4.4-es változatát, ugyanis a programban (amely egyébként egy videokódoló) ki-be kapcsolgathatóak a használt utasításkészletek. Érdekes eredményeket kaptunk, itt a K7 nem kapott szerepet.

Vegyük sorban az egyes architektúrákat. Az AMD K8 az SSE–SSE2 bekapcsolása során semmit nem gyorsult, ez annak tulajdonítható, hogy a K8-ban még 64 bites SSE-végrehajtók vannak, márpedig ez azt jelenti, hogy a CPU egy SSE2 utasítást (packed double precision) két macro-opra kénytelen dekódolni, így semmivel sem vagyunk előrébb ahhoz képest, mint amikor két FPU-műveletet hajt végre a processzor. Az SSE3 bekapcsolásával már gyorsult a K8, de sebessége nem érte el a K10 simán SSE-vel elért idejét. A K10 már kétszeres sebességgel hajtja végre az SSE2 utasításokat, így az eredeti sebességhez képest 17%-ot gyorsul. Az SSE3 bekapcsolásával további 12%-ot nyer a processzor.

Kicsit más a helyzet a Core processzorokkal. Az SSE2 bekapcsolásával a Merom 24%-ot nyert az eredeti sebességhez képest. Ugyanakkor az SSE3 bekapcsolása lassította a CPU-t. Hogy miért, annak utána kellett nézni, mert a tesztidők többszöri megismétlésre sem változtak. Mint kiderült, az SSE3 utasításkészletben az LDDQU utasítást szánták a videotömörítés gyorsítására, ami a Pentium és AMD processzorokon nagyon szépen működik is, viszont a Core processzorokat „nem szereti”, helyette a PALIGNR-t tanácsos használni. Tesztünk szempontjából ez irreleváns, mivel a programot nem mi írtuk, így nem is tudunk változtatni rajta. Mindenesetre az SSSE3 bekapcsolása után a Core az SSE2-es eredményhez képest további 10%-ot gyorsult, így az eredetileg mért idő 66%-t érte el. A Penryn ismét más tészta. Az SSE2 bekapcsolása 28%-os előnyt jelent ennél a processzornál, és az SSE3 sem rontott jelentősen a helyzeten, míg a Merom 10, addig a Penryn összesen 2 másodpercet lassult. Az SSSE3 bekapcsolása után további 11% volt a jutalmunk, és az SSE4.1 még 5%-ot gyorsított. Nagyon jól látszik, hogy az egyes architektúrák mire képesek egy jól optimalizált kóddal (tekintsünk el a Merom SSE3-as esetétől), ezek a tesztek megmutatták, hogy alapjában véve az SSE-végrehajtás a Core processzoroknak jobban fekszik.

Érdekesség gyanánt a Sandra 2007 tesztelésével is próbálkoztunk, de ez a program szemmel láthatóan optimalizálatlan, az AMD processzorokon indokolatlanul alacsony eredményeket értünk el. Az Integer tesztekben az SSE2 bekapcsolása semmit nem gyorsított a K10-en, és az FP-tesztekben is minden logikát nélkülöző módon viszonyultak egymáshoz a K8 és K10 architektúrák.

A cikk még nem ért véget, kérlek, lapozz!

Azóta történt

Előzmények