Bevezető
Az elmúlt hónapokban sok minden történt a processzorok világában. Leginkább szembeötlő újdonság az AMD új architektúrájára épülő processzorok bejelentése volt, de nem sokkal előtte az Intel is előrukkolt a továbbfejlesztett Core architektúrára épülő Penryn lapkáival. Tisztában vagyunk azzal, hogy az olvasók legfőképpen a Phenom processzorok képességeire kíváncsiak, és meg is értjük őket, de ezúttal rendhagyó módon a konkrétan a Phenommal foglalkozó cikkünk előtt előétel gyanánt egy a szokásostól eltérő elemzést is készítettünk. Ebben megpróbálkozunk az AMD előző három CPU-generációjának architekturális összehasonlításával, illetve ezeket összevetjük az Intel Core két „alfajával”, a Merommal és a Penrynnel (az Intel a mobil lapkák után nevezi el az egyes családokat).
Tesztünkben a szokásos alkalmazástesztek helyett főképpen szintetikus benchmarkokra támaszkodunk, ami tőlünk teljesen szokatlan, de ezúttal elsődlegesen arra vagyunk kíváncsiak, hogy az AMD mit alkotott az elmúlt nyolc évben (a K7 1999-ben jelent meg), és ezt benchmarkokkal lehet a legjobban kimutatni. Persze ha már ebbe belemerülünk, azt is megnézzük, hogy a Penryn miben és miért lett jobb, mint a Merom. Összegezve tehát ezúttal nem egy szimpla processzortesztet adunk közre, sokkal inkább a miértekre próbálunk választ adni. A cikk feltételezi, hogy az olvasó valamilyen szinten tisztában van az AMD és Intel architektúrák főbb jellemzőivel, ezeket egy korábbi cikkünkben már összegeztük, ugyanakkor megpróbáltuk minél érthetőbben, emészthetőbben és érdekesebben megfogalmazni a problémákat és megoldásokat.
Cikkünk négy fő részre osztható, először a cache-hierarchiával foglalkozik, a gyorsítótárak sebességével és tulajdonságaival. A cache a valós alkalmazás során nem választható el a memóriahasználattól, de mi ezúttal különvettük a kettőt, így cikkünk második fejezetében a memóriakezelést tárgyaljuk, amire a K10 új memóriavezérlője miatt van szükség. A harmadik rész a processzorok utasításvégrehajtásával foglalkozik, az egyes végrehajtóegységek sebességével, utasításkészletek implementációjának előnyeivel, hátrányaival, végül kipróbálunk pár olyan programot, melyek az architektúrák tipikus erősségeit/gyengéit fedik fel.
Tesztünk egyik érdekessége, hogy a programok többségét egy szálon teszteltük, ráadásul azonos órajelen (2 GHz), így ki tudtuk mutatni, hogy az adott feladat megoldásában az egyes architektúrák mennyit fejlődtek elődeikhez képest – gondolunk itt a K7–K8–K10 váltásra, illetve a Merom–Penryn duóra –, és azt is, hogy az AMD és Intel processzorok hogyan viszonyulnak egymáshoz. Azt ne feledjük el, hogy a K8, K10 és Core processzorok már többmagos működésre kihegyezve látták meg a napvilágot, tehát amikor egy szálon tesztelünk, nem biztos, hogy megmutatkoznak a többmagos struktúrák korlátai vagy éppen erősségei, ezért is csak elméleti jelentőségűként szabad az eredményeket felfogni.
Gyorsítótárak
Processzor megnevezése | AMD K7 | AMD K8 | AMD K10 | Intel Merom | Intel Penryn |
L1 cache | 64 kB adat 64 kB utasítás (2 utas, 64 byte line hossz) | 32 kB adat 32 kB utasítás (8 utas, 64 byte line hossz) | |||
L1I cache szélessége | 128 bit | 256 bit | ? bit | ||
L1D cache szélessége | 2 x 64 bit load 1 x 64 bit store | 2 x 128 bit load 2 x 64 bit store | 1 x 128 bit load 1 x 128 bit store | ||
L2 cache | 256–512 kB (16 utas; 128 bit; 64 byte line hossz) | 512–1024 kB (16 utas; 128 bit; 64 byte line hossz) | 512 kB (16 utas; 256 bit; 64 byte line hossz) | 4 MB megosztott (16 utas; 256 bit; 64 byte line hossz) | 6 MB megosztott (24 utas; 256 bit; 64 byte line hossz) |
L3 cache | nincs | 2 MB (32 utas; 128 bit) | nincs |
Tesztünk első fejezetében tehát a gyorsítótárrakkal foglalkozunk, vagyis az L1, azaz elsőszintű és L2, azaz másodszintű cache-ekkel. Az L1 cache-ről tudvalevő, hogy a regiszterek után a leggyorsabb átmeneti tároló, amivel a processzor dolgozhat. Napjainkban a processzor órajelén fut, mérete pedig igen pici, az AMD esetében 2 x 64 kB, a Core CPU-kban pedig 2 x 32 kB. Nem minden a méret, a gyorsítótárak feltérképezése során szót kell ejteni az asszociativitásról is. Az AMD 2 utas, míg az Intel 8 utas csoportasszociatív L1-es gyorsítótárakat alkalmaz. Mit is jelent ez?
Hirdetés
Az n-utas csoportasszociatív gyorsítótárak esetében a cache set-ekre (nevezzük őket blokkokra) van osztva, ezek a blokkok pedig n darab cache-vonalat (nevezzük őket celláknak) tartalmaznak. Egy kis számolás után adott számú memóriablokkhoz hozzárendelődik egy cache-blokk, így az adott memóriablokkból n darab cím tárolható el a cache-blokkban.
Vegyük alapul az AMD processzorokat, 64 bájtos cache-szervezés esetén (az AMD és az Intel is 64 bájt méretű cache-cellákkal dolgozik) a 64 kB méretű L1 cache 1024 darab cache-cellára oszlik ([64 x 1024 bájt] / 64 bájt cellaméret). Maradva a példánknál, ha 2 GB rendszermemóriánk van, akkor azt az AMD processzorok 512 darab 4 MB-os blokkra osztják fel (2048(MB memória)/1024(db cella)x2 (utas)=4), majd minden egyes memóriablokkhoz hozzárendelődik egy cache-blokk, ami n-utas, esetünkben kétutas, tehát a 4 MB-os blokkok megcímzése a processzorcache-ben kétfelé oszlik. És most jön a lényeg. Amikor a processzornak szüksége van egy memóriában található adatra, a cache-vezérlés betölt egy sort (64 bájt) a memóriából a hozzárendelt cache-blokkba, azon belül az egyik cellába, így amikor a CPU-nak később is szüksége lesz erre vagy egy pár bájttal később megtalálható adatra (64 bájton belül maradva), már nem kell a memóriához nyúlnia, hiszen az megtalálható lesz a sokkal gyorsabb cache-ben, pontosabban AMD processzorok esetén a blokk egyik cellájában (Core processzoroknál nyolcutas a cache, tehát nyolc helyre lehet elhelyezni ezt az adatot). A tár minél több utas, annál magasabb a találati arány, viszont annál lassabb benne a keresés. Két eset lehetséges. Az egyik, amikor a rendszermemória adott blokkjából kiolvasunk egy adatot, az ehhez rendelt cache-blokk legutoljára feltöltött (LIFO) vagy legrégebben használt (FIFO) cellája átkerül a cache-hierarchia következő elemébe, helyére pedig az újonnan bejövő adatok kerülnek. A másik, amikor a cache a használatba vételek arányában szortírozza az adatokat (L[east] R[ecently] U[sed]). Ha kétutas a cache, akkor az adott blokkból minden második betöltés az egyik cache-cella felülírását eredményezi, márpedig ha sűrűn kell ugrándozni a memóriában mondjuk három egymáshoz közel, de 64 bájtnál távolabb elhelyezkedő memóriacím között (például ezerszer lefutó ciklus esetén), akkor ez nem igazán optimális. A Core processzorokban nyolcutas csoportasszociatív L1 cache található, ami egyrészt azt jelenti, hogy az adott blokkon belül csak minden nyolcadik memóriabetöltés igényli a 64 bájtos cella felülírását, ugyanakkor viszont a keresési idő a legrosszabb esetben akár négyszeresére is nőhet, ha a 2-utas megoldáshoz hasonlítjuk.
Kicsit elkalandoztunk a témától, ugyanis a n-utas csoportasszociativitással együtt járó különbségeket pont hogy nem mértük le, de azért érdemes felfrissíteni ismereteinket. Számunkra most először is az L1D cache sebessége fontos, amit a gyártók szépen fel is szoktak tüntetni a dokumentációkban. Lássuk, itt mi történt az elmúlt években. Az AMD Athlon processzorok (K7) órajelenként két 64 bites olvasásra és/vagy egy 64 bites írásra képesek. Talán hihetetlen, de ezt a konstrukciót az Athlon 64 is megörökölte, napjainkra már nem ez a leggyorsabb megoldás, korábbi Athlon 64-es tesztjeinkben nyilvánvalóvá is vált, hogy ez a keskeny útvonal olvasásnál és írásnál is visszafogja a processzort. Akkor vált láthatóvá, amikor az órajel emelésével együtt nőtt a memóriaolvasás/írás sebessége is (lásd például itt). A K10-ben az olvasás és az írás is duplájára gyorsult, de eltérő módon. Az olvasások szélessége megduplázódott, tehát a K10 órajelenként 2 x 128 bites olvasásra képes. Ezzel szemben az írás szélessége nem változott, viszont immár két port képes írni, igaz, ezek még mindig csak 64 bit szélesek, ezzel együtt jár, hogy a 128 bites utasításokat a K10 kétszer 64 bites formában tárolja el. Az Intel processzorok másképpen működnek, már a P6 óta két egymástól független olvasó és író port van, a Core processzorokban ezek 128 bit szélesek.
Az AMD a másodszintű gyorsítótár méretére a K8 megjelenése óta nem fektet túl nagy hangsúlyt. A K7 processzorokban 256–512 kB található (akkoriban még a magméret, azaz a gyártástechnológia korlátozta a gyártót), az Athlon 64-ben maximum 1 MB a mérete, a K10-ben pedig megelégedtek az 512 kB-tal. Ezzel szemben az Intel már a Pentiumok L2-es gyorsítótárát is szerette növelni, és ez még inkább igaz a Core processzorokra, a Merom 4 MB, a Penryn pedig 6 MB másodszintű gyorsítótárral rendelkezik, duplamagonként. Az AMD azért nem növeli meg jobban az L2 cache méretét, mert az integrált memóriavezérlő (amelyről később még szó esik) gyorsan hozzáfér a memóriához, így a cache által biztosított gyorsabb adatelérés (alacsonyabb késleltetés/várakoztatás) nem igazán mutatkozik meg a mindennapi használatban, ezt láthattuk is K8-as elemzéseinkben. Az Intel ezzel szemben szeret az L2 cache-re támaszkodni, mert a processzor csak a lassú rendszerbuszon keresztül éri el a rendszermemóriát, ezért a cache méretének növelése szignifikáns gyorsulással jár együtt.
Táblázatunkból kiolvasható, hogy az AMD a K10 esetében egy 2 MB méretű harmadszintű gyorsítótárat is alkalmazott. Mit érdemes erről tudni? Az L3 cache egészen mostanáig egyfajta luxust jelentett, gyakorlatilag csak szerverprocesszorok esetében láthattunk példát az alkalmazására. Miért? Azért, mert a cache kialakítása drága, fajlagosan sokkal drágább, mint az egyszerű alaplapba passzintható memóriamodulok. Az AMD a K10 esetében azért döntött az L3 cache használata mellett, mert a K10 úgynevezett natív négymagos processzor, egyetlen lapkán találunk négy központi egységet, ez a harmadszintű gyorsítótár pedig úgy készült, hogy mind a négy mag hozzáférhessen, gyakorlatilag összekösse őket. A megoldásnak vannak előnyei és hátrányai is. Az előnyök között lehet felsorolni, amikor több szálon futó (tehát több processzormagot megdolgoztató) alkalmazások arra kényszerítik az egyes központi egységeket, hogy ugyanazon adatokkal dolgozzanak, ilyenkor az adatokat elég egyszer eltárolni (az L3 cache-ben), az összes processzormag ugyanolyan sebességgel fér hozzájuk. Gondoljunk bele, az Intel négymagosa ezzel szemben két darab 4–6 MB méretű gyorsítótárat alkalmaz (kétmagonként egyet); ha az egyik processzorpár (egyik elemének) szüksége van a másik pár gyorsítótárában megtalálható adatra, akkor azt kénytelen a rendszerbuszon keresztül lekérni, ami rengeteg ciklusnyi időkiesést jelent. Kérdés viszont, hogy ez mennyire ütközik ki egy átlagos felhasználói környezetben? Valószínűleg nem túlságosan, hiszen még nagyon kevés az olyan program, mely egyszerre kettőnél több szálon képes dolgozni és sok memóriát is igényel.
Ugyanakkor vannak hátrányai is. Egyik hátránya, hogy az L3 cache relatíve lassú. Méretéből és kialakításából kifolyólag csak lassabb elérésű memóriacellákból épülhet fel, összehasonlításul a K10 L1 cache 3 ciklusnyi, az L2 cache 9 ciklusnyi, az L3 pedig legalább 20 ciklusnyi késleltetésű. A második probléma, hogy sokkal bonyolultabb cache-koherenciakezelő logikára van szükség az adatfüggőségek kezelésére, amikor már 3-4 mag dolgozik egyszerre. Összességében tehát az L3 alkalmazásának előnyei és hátrányai arányban állnak egymással, ami ez esetben nem túl pozitív kicsengésű, hiszen jobb lenne, ha az előnyök felé billenne a mérleg.
Lássuk, hogy az egyes generációk gyorsítótárai milyen sebességgel rendelkeznek. A tesztek 2 GHz-es órajelen születtek 10 x 200 MHz-es beállítás mellett.
Először az L1D cache sebességére voltunk kíváncsiak, az eredmények egyértelműek. A K7 és a K8 egy kis különbséget leszámítva ugyanúgy teljesített, 2 GHz-es órajelen az elérhető maximális olvasási sebesség 32 000 MB/s, ez stimmel is (ciklusonként 2 x 64 bit). Az írás csak 1 x 64 bit széles, így az elérhető maximum 16 000 MB/s, ez is stimmel (az Athlon 64-ünk 2003 MHz-en járt, itt pedig 16 024 MB/s). A másolás egy igencsak becsapós téma. Az Everest készítőivel konzultálva sikerült kideríteni, hogy minek köszönhető az olvasásnál alacsonyabb, de az írásnál magasabb érték. Az Everest Copy az L1D cache méretének felét olvassa ki és írja vissza, amiben pontosan az a jó, hogy így a teljes copy rutin az L1D cache adataival dolgozik, és kibukik, ha függetlenek a load/store portok. Mivel minden az L1D-n belül történik, ennek nincs köze se a prefetcherekhez, se a memory disambiguationhöz. Ha a portok függetlenek, akkor a portok olvasási és írási sebessége összeadódik. Ha nem függetlenek, akkor az kiütközik. A K7/K8-ak egyik portja képes a 64 bites olvasásra, míg a másik port egyidejűleg tud írni és olvasni is. A másolás során összeadódik az egyidejű olvasási és írási sebesség (64 bit + 64 bit), így a másolás sávszélessége nagyobb az olvasásnál, de nem duplája az írásnak egyfajta cache-megvalósításbeli jellemző miatt. A K10 eredményei egyértelműbbek, az új architektúra 2 x 128 bit olvasására és 2 x 64 bit írására képes órajelenként, ennek megfelelőek az adatok. A másolást korlátozza a 2 x 64 bites írás sebessége, ezért a K10 itt ugyanolyan gyors, mint írásban. A Core processzorokban két 128 bites port van, ezek egymástól teljesen függetlenül működnek. Ez jól is látszik, az olvasás és az írás ugyanolyan gyors, míg a másolás során összeadódik a két port sebessége.
A másodszintű gyorsítótár sebességének leméréséhez ugyanúgy 2 GHz-es órajelet alkalmaztunk. Itt már kicsit bonyolultabb a téma, mert eltérő késleltetéssel eltérő sebességűek a gyorsítótárak. Az L1 esetében ez nem volt probléma, mert az összes L1-es cache késleltetése ugyanolyan mértékű volt, de az L2-nél ez már többé nem igaz. Ami jól látható, az az, hogy a K7 és a K8 itt is közel ugyanolyan gyors, a K8 picit lassabb, mert a cache elérési ideje hosszabb (Brisbane-t teszteltünk). A K10 már egy teljesen felújított architektúra ebből a szempontból is, az L2 cache elérése 256 bitre szélesedett (bár hallottunk 128 bites pletykákat is), ráadásul késleltetési ideje is csökkent, így a K8-hoz képest a gyorsulás olvasásban 2,5-szeres, írásban 2-szeres, másolásban pedig szintén majdnem annyi, mint olvasásban. A Merom és a Penryn a K10-hez hasonlóan szerepelt, de a nagy, 4–6 MB méretű gyorsítótárak elérési ideje hosszabb, mint a K10-é, és valószínűleg az L2 feltöltését az L1 sebessége is meghatározza, így olvasásban lassabbak annál, írásban és másolásban viszont gyorsabbak.
A késleltetési időket ábrázoló grafikon beszédes, az L1-es cache-ek elérési ideje minden processzornál azonos, 1,5 ns volt. A gyártók minden esetben 3 ciklust specifikáltak, tehát az Everest jól mért. A K7-es másodszintű gyorsítótára fél nanoszekundummal gyorsabb a K8-énál, viszont a K10 nagyot lépett előre, esetében 35%-kal kisebb késleltetésről beszélhetünk. A Merom és Penryn viszonya is érdekes, bár a Penryn jóval nagyobb L2-es cache-sel rendelkezik, késleltetése is magasabb lett.
Bevetettük a közkedvelt Sciencemarkot is, amivel szintén figyelemreméltó eredményeket kaptunk. Nem tudjuk, hogy a program pontosan milyen módon teszteli a processzorokat (nem 100%-ig biztos információink vannak arra vonatkozólag, hogy másolást [is] mér), de ami biztos, hogy elavultabb technikákkal, mint az Everest, hiszen már két éve nem nyúlt hozzá programozó, így az SSE3-nál újabb utasításkészleteket nem is támogatja. A Sciencemark különbséget mért ki a K7 és a K8 L1-es gyorsítótára között is, a K10 nem gyorsult kétszeresére a K8-hoz képest, és szépen lemaradt a Core architektúrára épülő processzoroktól. Arra tudunk gondolni, hogy valóban közrejátszhat a másolási sebesség, és itt az L1I is szerepet játszhat (+prefetch), másképpen nem lehet gyorsabb a Merom és a Penryn. Az L2 cache méréseknél már nem volt különbség a K7 és a K8 között, viszont ebben a K10-en a K8 dupláját mértük, az Intel CPU-i pedig még gyorsabbak voltak, de azonos sebességűek, ami már csak az elérési idők miatt is kétséges. Összegezve inkább az Everestnek hiszünk, abban logikus eredményeket kaptunk.
Everest benchmarkok | Olvasás (MB/s) | Írás (MB/s) | Másolás (MB/s) | Késleltetés (ns) |
AMD K10 L2 cache (2 GHz) | 16 015 | 11 412 | 14 865 | 4,6 |
AMD K10 L3 cache (1,8 GHz) | 7478 | 7131 | 9168 | 9,1 |
AMD K10 L3 cache (2,2 GHz) | 7558 | 8303 | 10 854 | 8,2 |
AMD K10 memória (unganged mód - 2,2 GHz) | 7531 | 5382 | 8286 | 59,3 |
Utolsóként a K10-en található L3-as gyorsítótárat vetettük össze a K10 memóriaelérésével, a táblázatból jól látszik, hogy miért. Az L3 olvasása semmivel sem gyorsabb, mint a memória olvasása, írásban már van 32% különbség, viszont másolásban megint csak 10%-ot mértünk ki. Az egyetlen komoly differenciát a késleltetés mutatta, a cache-hez természetesen sokkal gyorsabban férünk hozzá, mint a memóriához. Ha tehát csak a sávszélességet vesszük figyelembe, az L3 nem muzsikál túl jól. De ne feledjük el, hogy az L3 praktikus okokból került a processzorba, ez egy olyan tárterület, amit a négy processzormag együttesen használ, és ha olyan adatokra van szükség, amit több mag is igényel, akkor jobban járunk a cache-sel, mint a memóriával.
Memóriakezelés
Processzor megnevezése | AMD K7 | AMD K8 | AMD K10 | Intel Merom | Intel Penryn |
Támogatott memória | DDR-400 | DDR2-800 | DDR2-1066 DDR3 (később) | DDR2-800 (hivatalosan, de egyébként 1066 is) DDR3-1333 | |
Maximálisan elérhető memória-sávszélesség | 6,4 GB/s | 12,8 GB/s | 17 GB/s (DDR2) DDR3 (később) | 12,8 GB/s (DDR2) 21 GB/s (DDR3) | |
Rendszerbusz órajele | 200 MHz FSB Alpha EV6 (3,2 GB/s) | 1000 MHz HyperTransport (8 GB/s) | 1000–2600 MHz HyperTransport (8–20,8 GB/s) | 333–400 MHz FSB AGTL+ (10,6–12,8 GB/s) | |
Hardveres prefetch (CPU-magonként) | Unit-stride prefetcher (L2) | Unit-stride prefetcher (L2) | 2 db Memory prefetcher (RAM); Unit-stride prefetcher (L1); Adaptive prefetcher (L1) | Utasításbehívás és predekód prefetch; Data Cache Unit prefetcher (L1); IP-based prefetcher (L1); 2 db Data Prefetch Logic (L2, azaz megosztott) |
Tesztünk második fejezetében a rendszermemória elérésével foglalkozunk. A memória elérésének tesztelésére ezúttal azért fordítottunk külön figyelmet, mert a K10 megjelenése új ajtókat nyitogatott ezen a téren is. Az új architektúrában még mindig integrált memóriavezérlő dolgozik, de az AMD félretette a több éve mindkét gyártó által legszívesebben használt kétcsatornás működést, és dupla egycsatornás kiépítést fejlesztett ki. Erre miért volt szükség? A hagyományos kétcsatornás memóriaelérésnek az az előnye, hogy egyszerre nagyobb adatmennyiséget lehet rajta átmozgatni, de órajelenként csak egy műveletre (olvasás vagy írás) van lehetőségünk, ami nem optimális az egyre terjedő multitaszkos, egyre több szálon dolgozó környezetekben, amikor esetleg több operációs rendszer és azokon belül több program is egyszerre szeretné elérni a memóriát írásra és olvasásra egyaránt – gondoljunk a virtualizáció térhódítására. Az AMD megoldása kézenfekvőnek tűnik, az új memóriavezérlő órajelenként két műveletet képes elvégezni. De hogy a gyakorlatban ez mit jelent, arra külön kíváncsiak voltunk.
A tesztekben ezúttal is a K7–K8–K10 trió és a Merom–Penryn duó kapott szerepet. Ha emlékszünk még az Athlon 64 előtti időkre, felsejlik, hogy az AMD akkoriban még egy pont-pont összeköttetést, az DEC Alpha által kifejlesztett EV6 processzor rendszerbuszát használta a processzor és az északi híd összekapcsolására. Az EV6-ból származó busz előnye elsődlegesen abban rejlett, hogy riválisánál, a Pentium Próban debütáló GTL rendszerbusz továbbfejlesztett variánsainál nagyobb sávszélességet kínált, többutas rendszerekben pedig dedikált útvonalat biztosított minden végrehajtóegység számára, míg az akkor használatos 440BX csak egy közösen használható rendszerbuszt áldozott fel erre a célra. Az AMD a K8-ban mégsem az EV6-ot vitte tovább, hanem úgy döntött, hogy a memóriavezérlőt egyszerűen a processzorba integrálja (az Alpha az EV7 esetében is éppen így tett). A kétcsatornás memóriavezérlővel rendelkező asztali K8-asok (először S939, majd AM2 platformon) megduplázták az elméletileg elérhető maximális memória-sávszélességet. Ez szép és jó volt, de nem sokat értünk vele, hiszen kétmagos Athlon 64 processzorunk magjai egyetlen közös memóriabuszon voltak kénytelenek osztozni. A megoldás kiegyensúlyozatlan, mert egyszerre csak az egyik processzormag kérhet/küldhet ezen keresztül adatot, miközben olyan magas sávszélesség áll a rendelkezésére, amit soha nem képes kihasználni. A K10-nél egy ilyen esetben már nem egy, hanem két processzor juthat hozzá az igényelt adatokhoz egyetlen ciklus alatt, igaz, az egycsatornás sávszélesség csak fele a korábbinak, mégis ez a jobb megoldás, mert így két processzormag igényeit elégítettük ki egyetlen ciklus alatt ahelyett, hogy egyetlen processzormagra pazaroltuk volna el az összes erőforrást (sávszélességet).
Az Intel esetében más a helyzet, a Core processzorok a rendszerbuszon keresztül kapcsolódnak az északi hídhoz, ami összeköttetésben áll a memóriával. Ha a négymagosokat vesszük alapul, a két kétmagos processzor egyetlen ciklus alatt elküldheti/fogadhatja a szükséges adatokat, ha éppen a rendszerbusz szűkössége ebben nem akadályozza meg. Ha a rendszerbusz nem szűkös, a chipset még akkor is órajelenként csak egyetlen memóriaműveletet tud elvégezni. A helyzet az, hogy átlagos, mindennapi felhasználást feltételezve nem jelent korlátot sem a rendszerbusz, sem a kétcsatornás memóriavezérlő (illetve az órajelenkénti egyetlen művelet). Ugyanez igaz a K8 processzorokra is. A K10-et tehát inkább az erőteljesen többszálú környezetek igényeit figyelembe véve fejlesztették ki, ezt nem is tagadja a gyártó.
Egyszerű halandó felhasználók számára tehát az AMD új megoldása nem fog érzékelhető többletet jelenteni, ez egészen biztos. De azért mi megpróbáltuk kimérni, hogy mennyi az előnye. A grafikonok megértéséhez annyit kell tudni, hogy az AMD (illetve az alaplapgyártók) a K10 esetében a kétcsatornás működést GANGED (’csoportba foglalt’ – utalva a két memóriacsatorna együttes működésére), az egycsatornás vezérlést pedig UNGANGED elnevezéssel illették. A BIOS lehetőséget ad arra, hogy kiválasszuk a nekünk szimpatikusabb változatot. Első körben az egy szálon futó memóriateszteket vettük elő, ilyen az Everest is.
Az Everest lineárisan végzett mérései szerint a K7 éppen eléri a 3,2 GB/s-os sávszélességet. Hiába a kétcsatornás DDR400-as működés, tehát a 6,4 GB/s-os elméleti maximum, ez egyszerűen nem használható ki, mivel a processzor 200 MHz-es FSB-n fut, ezen az órajelen pedig 3,2 GB/s a chipset és a processzor közti sávszélesség.
A K8 esetében már más a helyzet, hiszen a memóriavezérlő a processzor órajelén fut, tehát az elméletileg elérhető sávszélességet a memória órajele és a memóriavezérlő hatékonysága határozza meg. Mi kétcsatornás módban, DDR2-800-as memóriákkal, 1T-s command rate érték mellett teszteltük a K8-at, ahol is az elérhető maximum 12,8 GB/s, az architektúra azonban olvasásban csak 52, írásban pedig mindössze 44%-osan használta ki ezt, míg a másolás 54%-os volt. Ne feledjük, hogy ezek egyetlen szálon mért értékek, tehát hiába két- vagy négymagos a CPU, csak egyetlen processzormag memóriaelérési sebességét tükrözik. Mindezt látva akár arra is gondolhatnánk, hogy a K8-as memóriavezérlője igen hatékony, hiszen egymagos elérésben az elméleti maximum felét az íráson kívül mindenhol hozta, tehát ha két maggal számolunk, és megszorozzuk az értékeket kettővel, akkor úgy tűnik, hogy a K8 az egész rendelkezésre álló sávszélességet ki tudja használni.
Az AMD K10 első látásra nem változott túl sokat ezen a téren. Ezt a processzort már DDR2-1066-os órajelen teszteltük, a ganged és unganged mód között csak olvasásban mértünk ki különbséget, ami jól mutatja, hogy egyetlen szálon terhelve az unganged mód nem tud előnyt kovácsolni a gangeddel szemben, és persze az is látszik, hogy egyetlen processzormag nem képes ennél nagyobb adatmennyiség megmozgatására. Írásban a K10 lassabb volt a K8-nál, másolásban viszont gyorsabb.
Az Intel processzorok is változásokon mentek keresztül, a Merom olvasásban gyorsabb a Penrynnél, köszönhetően a kisebb késleltetésnek. Írásban viszont a Penryn a gyorsabb az írási rutin SSE4.1-es támogatása miatt. Másolásban ugyanolyan gyorsak voltak. A Core-t a K8/K10-zel összehasonlítva nagyon jól látszik, hogy a két implementáció szöges ellentéte egymásnak, az integrált memóriavezérlővel szerelt AMD processzorok sokkal gyorsabban férnek hozzá a memóriához, viszont erre szükségük is van, mert a gyorsítótárak mérete jóval kisebb.
Sciencemarkkal is leteszteltük a memóriaelérést, ez a program is egy szálon dolgozik. A pontos mérési módszereket nem ismerjük, de annyi azért itt is látszik, hogy az IMC-vel rendelkező AMD processzorok komoly fölényben vannak.
Ezek után a memóriaelérési, azaz késleltetési időkkel foglalkoztunk. Elsőként az Everest benchmarkjával teszteltünk, ez lineáris elérési időt mér. Itt is jól látszik, hogy a rendszerbuszos processzorok (K7, Merom, Penryn) hátrányban vannak az IMC-sekkel szemben. Érdekesség, hogy a K10 lassabb volt a K8-nál. Ez minek tulajdonítható? Mivel a K10 már közvetlenül az L1-be olvas, így az L3 cache "kivonható" az egyenletből, ezért csak arra tudunk gondolni, hogy az új memóriavezérlő egy picit lassabban éri el a memóriát, mint elődjében. A teszt azt méri, hogy a memóriaolvasási parancs kiadásától számítva mennyi idő telik el, míg az adat megérkezik a regiszterekbe. Az új memóriavezérlő lineáris elérést feltételezve 7–8 ns-mal lassabb, mint elődje. De mi a helyzet akkor, ha nem lineáris elérést mérünk? A processzor számára szükséges, memóriában található adatok nem csak lineárisan helyezkedhetnek el.
A problémát a legjobban egy LATER nevezetű programmal tudtuk illusztrálni, az alkalmazás a memória véletlenszerű elérését méri kétféle módon, egyrészt az L1-es cache-t is bevonva a munkába, másrészt az L1-et kivonva a forgalomból. Érdekes eredmények születtek. A K7 közel olyan gyors volt (80–100 ns), mint lineáris olvasásban. Jóindulattal ez a K8-ra is igaz (40–70 ns), viszont a K10 eredményei megugrottak, a lineáris olvasásban elért 60 ns-hoz képest 120–160 ns-os értékeket mértünk. Gondolhatnánk azt is, hogy ez egyrészt az L3 cache-nek tulajdonítható, de mint már tudjuk, a K10 közvetlenül az L1-be hívja az adatokat. A megoldás valószínűleg a prefetch logikában keresendő. Az AMD az előbehívók (prefetch) terén komoly változtatásokat eszközölt a K10-ben, a K8-ban egyetlen előbehívó volt, ami az L2-be dolgozott, a K10-ben viszont már két L1-es prefetcher és két memória-prefetch egység található. A K10 gyengébb eredménye talán annak a számlájára írható, hogy míg a K8 egyszerűen csak olvas és olvas (nincs semmi, ami megszabná a következő beolvasandó adat címét), addig a K10-ben az adatelérést a prefetch munkája is befolyásolja. Lineáris elérésnél a prefetchnek nincs nehéz dolga, folyamatosan előretölti az adatokat, ezzel lerövidítve az adatelérés idejét, viszont amikor véletlenszerűen kell elérni a memóriát, a prefetch ha nem is minden egyes alkalommal, de sok esetben rosszul jósol, azaz rossz adatot tölt előre, ami óriási veszteséget okoz. Ezzel egyébként nincs is semmi baj, mert igen ritka az olyan eset, hogy összevissza kelljen ugrálni a memóriában, viszont ez a teszt fényt derített arra, hogy a K10 ezen a téren is megváltozott a K8-hoz képest.
Az Intel Merom a K10-hez hasonlóan viselkedik, viszont a Penryn eredményei előtt először kicsit értetlenül álltunk. A véletlenszerű elérés ilyen mértékű csökkenésére nem lehet kizárólagos magyarázat a megnövelt másodszintű gyorsítótár, itt valami másnak is történnie kellett. A megoldás valószínűleg a megnövelt szintű asszociativitásban keresendő, a Merom L2-es gyorsítótára 16 utas, a Penryné viszont 24 utas. Minél több cellára osztjuk fel a leképzett memóriablokkokat, annál nagyobb esélyünk van arra, hogy a cache-ben megtalálható a megcímzett adat, és annál ritkábban kell felülírni a cache-cellákat. Ha az asszociativitást is bevonjuk a képletbe, akkor érthető, hogy a K10 és a Merom közel megegyező eredményeket értek el. A K10 elsőszintű gyorsítótára csak kétutas, a Meromé nyolcutas, ebben a tekintetben a Merom előnyben van, viszont ezt az előnyt elveszti a rendszerbusz lassúsága miatt.
Az előzőleg tárgyalt programok sajnos csak egy szálon mérnek, ezért keresnünk kellett egy olyan benchmarkot, mellyel több szálon is képesek vagyunk a memóriaelérés tesztelésére. Végül megtaláltuk a Rightmark Multi-Threaded Memory Testet, ami pontosan erre lett kifejlesztve. A programmal annyi szálon lehet memóriaolvasást vagy írást végezni, ahány logikai processzort lát az operációs rendszer. Be kell állítani a tesztelés során használt memóriablokkok méretét, a művelet típusát (olvasás, írás, szoftveres prefetch-csel olvasás, non-temporal írás), a használt regiszterek típusát, ezek a:
- 64 bit MMX: MOVQ reg, [mem]; MOVQ [mem], reg és MOVNTQ [mem], reg
- 128 bit SSE2: MOVDQA reg, [mem]; MOVDQA [mem], reg és MOVNTDQ [mem], reg
lehetnek.
Beállítható a szoftveres prefetch hossza is. Mi 64 MB-os blokkokat alkalmaztunk (tehát a 64 MB-ot osztottuk annyi felé, ahány szálon folyt a tesztelés, két szálon 32 MB, négy szálon 16 MB), és 128 bites regisztereket használtunk. A program lényege tehát a több szálon végzett konkurens memóriaelérés tesztelése, ezzel egy csapásra le tudtuk mérni azt is, hogy memóriaolvasás és memóriaírás egyidejű végrehajtása során a K10 tényleg annyira jó-e (megjelent az írásokat tároló puffer), hogy a K10 több szálon mennyit fejlődött, és még azt is, hogy az Intel processzorok tényleg annyira rosszak-e, merthogy a fáma szerint a rendszerbusz szűkös négy Core-magnak, ezért szűk keresztmetszetté válik.
Az egyszerű olvasási teszt, mint neve is mutatja, egyszerűen a memóriaolvasást méri, az L2 cache is beleszól az eredménybe, az így kapott érték pedig az „átlagos”, mindennapi memóriaolvasást jelképezi.
Az olvasás szoftveres prefetch-csel egy szoftveres prefetch segítségével méri az olvasást, ezzel megkerülve az L2 cache-t valóban csak a maximálisan elérhető memóriaolvasási sávszélességet méri. Ez a módszer a processzor OoO-végrehajtását segíti ki azáltal, hogy előre betölti azokat az adatokat, amikre később szüksége lesz a végrehajtó egységeknek, így nem alakulnak ki függőségek és várakozási sorok, tehát gyorsul az adatfeldolgozás. A mindennapi életben ilyennel nem nagyon találkozunk.
Az írás egyszerű lineáris írást mér, az L2 cache sebessége is számít, az eredmény pedig amolyan átlagos, mindennapi írási sebességnek felel meg.
A non-temporal írás a cache-hierarchiát megkerülve, külön erre a célra bevezetett utasítások segítségével mér maximálisan elérhető, tiszta memóriaírási sávszélességet. Ez a módszer nagy mennyiségű adat kiírása során a cache olvasási/írási kényszere alól menti fel a processzort (ugyanis nem kell állandóan felülírni a cache-cellákat, lásd fentebb), így az írási sebesség drasztikusan megnőhet a sima íráshoz képest. A valóságban ezzel sem nagyon találkozni, csak speciálisan olyan feladatoknál, amikor erre van szükség.
A teszteket ezúttal a valós felhasználáshoz közelebbi beállítások mellett végeztük el, a K7 és K8-ason kívül minden processzor 2,66 GHz-en járt (Intel: 8x333, DDR3-1333, AMD K10: 10x266 MHz, DDR2-1066 beállítás, az L3 cache 2,13 GHz-en járt), a K7-et 2 GHz-en, a K8-at pedig 2,8 GHz-en járattuk DDR2-800-as memóriasebesség mellett.
Először a Rightmarkot is egy szálon teszteltük, elsőként a sima olvasással és írással, az eredmények, pontosabban az arányok nagyjából megegyeztek az Everestben mértekkel, bár a K7 és a K8 írásban itt rosszabbul szerepelt. A K10 ganged módban itt is gyorsabb volt egy hangyányival, mint unganged módban.
Szoftveres prefetch olvasással és NT-írással a K10-en kívül az összes architektúra feltámadt, a K10 csak írásban javult, de arányaiban nézve sokkal kisebb mértékben. A K7 NT-írása közel háromszor volt gyorsabb a sima írásnál, a K8 is több mint duplájára gyorsult, és a Core processzorok is háromszoros gyorsuláson mentek keresztül. Ez csak egyet jelenthet, hogy a K10-en a cache-hierarchia igen kiegyensúlyozott, és csak alig fogja vissza a memóriaelérést, legalábbis egy szálon futó alkalmazások esetén! Ezen nincs is miért meglepődni, hiszen az egyes processzormagok elkülönített másodszintű gyorsítótárral rendelkeznek, így az írásoknál nem kell a többi processzormag L1D gyorsítótárait frissíteni. Ezzel szemben a többi architektúra a memóriaműveletek során beleütközik valamiféle korlátba (cache-szervezés lassúsága, koherenciakezelés stb.), ami visszafogja teljesítményüket (közös L2 a Core processzorokban, keskeny adatútvonalak a K8-ban).
Két programszálon tesztelve az egyik szálon olvastunk, a másikon írtunk a memóriából/ba. A sima olvasási tesztekben a K10 unganged módban 24%-kal volt gyorsabb, mint ganged módban, és 37%-kal magasabb sávszélességet ért el, mint a K8. Ez egyértelműen arra utal, hogy a K10-ben egy továbbfejlesztett, és valóban többszálas működésre kihegyezett memóriavezérlő dolgozik. A K10 ganged, tehát kétcsatornás módban csak egy picit volt gyorsabb, mint a K8, amely szintén kétcsatornás módban működik. Érdemes a Core processzorokról is szót ejteni, négymagos Intel CPU-kat teszteltünk, tehát a 2 x 4–6 MB cache sokat nyom a latba. Olvasásban még nem maradtak le túlságosan a K10-től (a K8-nál gyorsabbak voltak, de ez a nagyméretű gyorsítótárak miatt nem túl meglepő), viszont írásban már igencsak lemaradoztak. Ha összeadjuk az egyes architektúrák olvasási és írási értékét, akkor sorrendben 5748, 7282, 6131, illetve 5272, 5250, 5691 és 5606 MB/s-ot kapunk. Mint látható, a legmagasabb értéket a K10 érte el unganged módban, a rendelkezésére álló 17 GB/s-nak az 42%-át, a Core processzorok a 21,3 GB/s-os sávszélességnek (DDR3-1333-as beállítás) mindössze a 26–28%-át képesek elérni, és ez még csak a kétszálas teszt volt. A Core processzoroknál érdemes külön figyelmet szentelni az eltérő magokon elindított tesztek eredményeire is, összességében ezekben az esetekben nem változott meg jelentősen a kép, az összeadott olvasási és írási eredmények alig térnek el egymástól.
A szoftveres prefetchelt olvasás és non-temporal store tesztben az arányok kicsit megváltoztak, de ez inkább csak a non-temporal store eredményekre igaz, az olvasási eredmények alig változtak. A K8 ismét több mint duplájára gyorsult. Ugyanez elmondható a K10-ről is, és a Core processzorok is több mint kétszeres gyorsulást mutattak be. Az egyszálas eredmények alapján a K8 és a Core architektúrák szereplése nem meglepő, és ha jobban átgondoljuk a dolgokat, akkor a K10 esetében sem. A K10-ben három gyorsítótár található, ezeket folyamatosan karban kell tartani, ami rengeteg „energiát”, sávszélességet igényel a processzortól, folyamatosan figyelni kell, hogy az egyes magoknak milyen adatokra van szüksége, frissíteni kell nem kevesebb, mint kilenc egymástól függő cache celláit, ez pedig itt szépen kibukott, ami egyébként nem probléma, mert a valós tesztben, tehát ahol számít, ott a K10 volt a leggyorsabb.
Következzenek a legérdekesebb eredmények, itt már négy szálon teszteltük a processzorokat, két szálon olvastunk, a másik kettőn írtunk. Ez a felállás nem mellesleg napjaink programjaiban igencsak valószínűtlen, de most architektúrák erősségeinek és gyengéinek felfedésére vállalkoztunk, ezért extrém körülményeket kellett teremtenünk. Az egyszerű olvasás-írás tesztben nyilvánvalóvá vált, hogy a K10 erre teremtetett, unganged módban sokkal jobban szerepelt, mint ganged módban, és gyorsabb volt a Core processzoroknál is. Érdekes látni, hogy ganged módban az egyes programszálak szinte hajszál pontosan ugyanakkora sávszélességet kaptak a processzortól, míg unganged módban a leglassabb írás is 29%-kal nagyobb sávszélességgel rendelkezett. Meglepő vagy sem, olvasásban a Core processzorok sem szerepeltek rosszul, viszont ne feledkezzünk meg arról, hogy ez egy négy szálon futó teszt volt, és a két írási szál jócskán lemaradt. Mindenesetre a K10 itt 7573 MB/s-ot, ezzel szemben a Penryn összesen csak 5455 MB/s-os össz sávszélességet tudott elérni. Utóbbi egyébként nagyjából megegyezik a kétszálas tesztben elért 5691 MB/s-mal, ami talán azt jelenti, hogy a rendszerbusz nem igazán szűk keresztmetszet, de ne felejtsük el, hogy ebben benne van a másodszintű gyorsítótár sebessége is.
Éppen ezért számunkra ebből a szempontból érdekesebb, beszédesebb a szoftveres prefetch-csel végzett olvasási és non-temporal írási eredmények összege. Mint látható, a K10 mindkét módban szépen begyorsult, de továbbra is az unganged mód maradt a király. Nagyon szép eredmény a K10-től unganged módban, hogy négy szálon terhelve képes a 17 GB/s-os (pontosabban 2 x 8,5 GB/s) sávszélességnek a 72%-át kihasználni (12 300 MB/s), ganged módban a kihasználtság csak 65%-os. Ha unganged módban a memóriacsatornák kihasználtságát nem együttesen értékeljük, akkor a 8,5 GB/s-os max sávszél 73 illetve 70%-a kerül felhasználásra. Az Intel processzorok legjobb esetben is csak 35%-ra képesek terhelni a memóriákat (7429 MB/s), de ha a rendszerbusz kihasználtságára vagyunk kíváncsiak, akkor a 10,6 GB/s értéknek a 70%-át éri el a Penryn – a legjobb esetben, de ez még mindig 40%-kal alacsonyabb érték, mint amit a K10 ért el, így kijelenthetjük, hogy ezen a téren tényleg a K10 a legfejlettebb architektúra. Szervervonalon az Intel-rendszer FB-DIMM memóriákkal valószínűleg jobban szerepelt volna, hiszen FB-DIMM-eket használva a memóriacsatornák számának növekedésével együtt növekszik a konkurens műveletek elvégzésének hatékonysága is (ahány modul, annyi konkurens olvasás-írás lehetséges), na de ez egy másik téma.
Utasítás-végrehajtás
Processzor megnevezése | AMD K7 | AMD K8 | AMD K10 | Intel Merom | Intel Penryn |
Futószalag hossza (lépcső) | 10/15 (int/fp) | 12/17 (int/fp) | 14 | ||
Elágazásbecslés | BTB: 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ége | 16 bájt | 32 bájt | 16 bájt | ||
x86 dekódolók száma | 1 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) | 3 | 4+1 | |||
ROB mérete | 72 bejegyzés | 96 bejegyzés | |||
ROB kimeneteinek száma | 6 (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ódja | 54 férőhelyes (18 Int/Mem, 3x12 FP [64 bit]) RS | 60 férőhelyes (3x8 Int/Mem, 3x12 FP [64 bit]) RS | 60 férőhelyes (3x8 Int/Mem, 3x12 FP [128 bit]) RS | 32 férőhelyes RS (vegyes) | |
Integer végrehajtók száma | 3 teljes értékű ALU | 3 teljes értékű ALU + 1 ABM | 1 teljes értékű ALU + ALU branch + ALU Shift/Rotate | ||
FP végrehajtók száma | FADD + FMUL + FSTORE | FADD + FMUL + FSTORE (SSE mov) | FADD + FMUL/FDIV + FSTORE + FLOAD | ||
Órajelenkénti INT SIMD műveletek száma | 1 x 64 bit | 2 x 64 bit | 2 x 128 bit (+FSTORE SSE mov) | 3 x 128 bit | |
Órajelenkénti FP SIMD műveletek száma | 1 x 64 bit | 2 x 64 bit | 2 x 128 bit | 3 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.
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.
Néhány további jellemző alkalmazás és a következtetés
Az elért eredmények kommentálása, az okok kifejtése nem túl egyszerű a programok pontos ismeretének hiányában, ezért inkább csak címszavakban szólunk a különbségekről.
A Fritz benchmark az Everest CPU Queenhez hasonlóan az elágazásbecslési képességekre fókuszál, és mint látható, az eredmények nagyon hasonlatosak az Everest benchmarkjában elértekhez, a K10 és a Merom között mindkét tesztprogramban kb. 15% a különbség.
A SuperPI alap x87-es utasításokkal dolgozik, de megdolgoztatja a memóriát (cache-t) is, emiatt a K10 csúfosan szerepel a Core-hoz képest. A K10-ben található picike L2 és a lassú L3 cache nem tudja felvenni a versenyt a nagy és gyors Intel-féle gyorsítótárral.
A 7-Zip becsomagolási tesztjében a K10 és a Core közül utóbbi került ki győztesen, 32 MB-os könyvtármérettel teszteltünk, márpedig ide kell a gyors memóriaelérés, a Core processzorok nagyobb és gyorsabb másodszintű gyorsítótára itt is kiütközött. Kicsomagolásnál azért fordult a kocka, mert ott már nincs szükség a gyors memóriaelérésre, ezzel szemben a gyors ALU-k kellenek, amelyek dolgában a K10 jól áll.
A Cinebench egy render-benchmark, márpedig a renderelések általában az FPU-ra támaszkodnak. A 10-es változat tudtunkkal csak az SSE2-t támogatja, SSE-végrehajtásban pedig a Core a gyorsabb (2 x 128 bit vs. 3 x 128 bit), így előnye sem meglepő.
A Scimark2 egy tudományos matematikai számításokon alapuló Java benchmark. A benchmark öt résztesztet hajt végre, ezek a Fast Fourier Transform (FFT), a Jacobi Successive Over-relaxation (SOR), a Monte Carlo integration, a Sparse matrix multiply és a dense LU matrix factorization. Általánosságban elmondható, hogy komplex számolásokkal van dolgunk, lásd itt.
Konklúzió
Az eredmények önmagukért beszélnek. Cikkünk nem csak és kizárólag a K10-zel foglalkozott, de egyértelmű, hogy főszereplőt játszott kis darabunkban. Remélhetőleg sikerült kicsit jobban megismertetni az AMD és Intel processzorok lelkét, összességében különösebb meglepetéssel nem találkoztunk. Amit a szintetikus tesztekből le tudtunk szűrni, az az, hogy a K10 cache-szervezése pariban van a Core-ral, a memóriavezérlő jóval fejlettebb lett, viszont nagyon úgy tűnik, hogy egyszerű számolásban nem sikerült vele beérni az Intelt, a legtöbb esetben kisebb vagy nagyobb mértékben, de lemaradt a K10 már a Meromtól is, a Penryn csak ront az AMD helyzetén. Ezek persze csak szintetikus tesztek, a valós alkalmazásokban talán más kép fogad majd minket. Már csak egy-két hét és kiderül. A K10 2,95 GHz-es alapkivitelben érkezik.
fLeSs
A tesztben szereplő Merom és K8-as processzorokat az EndWare Kft., a Penrynt az Intel, a K10-est Oliverda, a K7-est pedig Tildy bocsátotta rendelkezésünkre. Köszönjük.