Megateszt: Intel CPU-k Nehalemtől Skylake-ig

Utánajártunk, hogy az elmúlt 7 évben miként változtak, mennyit gyorsultak az Intel egyes mikroarchitektúrái.

A Nehalemhez vezető út

A nyár végén megjelent Skylake processzorok alapja, a Nehalem már lassan 7 éve került piacra, a két mikroarchitektúra között pedig sok mindent történt. Ahhoz, hogy átlássuk pontosan, miként jutott el a Skylake-ig az Intel, első lépésként ugorjunk vissza az időben cirka 15-20 esztendőt.

A P6 család

A Core processzorcsalád nagyban alapoz az Intel által csak P6 családnak nevezett Pentium Pro (1995) - Pentium 2 (1997) - Pentium III (1999) triumvirátus felépítésére, ezért először érdemes áttekinteni ezek működését.

Ez a család az Intel első out-of-order szemlélettel készült dizájnja, amely belül a műveleteket soron kívül, azaz nem programsorrendben dolgozza fel. Természetesen kívülről úgy kell látszódjon, mintha a végrehajtás a program szerinti sorrendben történne, ezért a processzor a beérkező utasításokat dekóderek segítségével belső, elemi egységekre, úgynevezett mikrooperációkra, azaz µop-okra bontja, majd ezeket azonnal végrehajtja, amint rendelkezésre állnak a szükséges paramétereik, végül pedig újra programsorrendbe állítva őket véglegesíti az eredményeket. Ekkor természetesen kiderülhet, hogy a kiszámított eredményekre mégsem lesz szükség, például mert az elágazásbecslés rosszul jósolt, így figyelmen kívül kell hagyni ezeket, majd a helyes ágon újraindítani a végrehajtást; ezáltal a belső működés spekulatívvá válik.

Az x86-os utasítások alapvetően memóriából beolvasó (load), műveletvégző (operation vagy op) és memóriába tároló (store) műveletekből állhatnak, illetve mivel CISC, azaz komplex utasításkészletről van szó, ezek kombinációi is lehetségesek egy utasításon belül, load-op vagy load-op-store utasítások formájában. A P6 processzorcsalád tagjai dekóderek segítségével ezeket az utasításokat primitív µop-okra bontják, majd továbbhaladva a pipeline-ban a primitíveknek megfelelő végrehajtókat találunk, melyek kezelik ezeket, párhuzamosan. A primitív műveletek a következők lehetnek:

  • a load, azaz adatbetöltés egy megadott memóriacímről, 1 µop;
  • a tárolás, azaz adatírás egy megadott memóriacímre, 2 µop; az egyik a cím kiszámításához szükséges, a második a kiírandó adatot juttatja erre a címre;
  • op, azaz számítási műveletek, ebből egy utasításban általában 1 van, ami 1 µop-ot jelent, de bizonyos utasításokban akár több is lehet.


[+]

A fentiek alapján látható, hogy egy load-op vagy egy store utasítás 2 µop-ra, egy load-op-store utasítás általában 4 µop-ra bomlik, míg az adatbetöltés (load), illetve a regisztereken dolgozó számítási műveletek 1 µop-ra fordulnak le. Bizonyos utasítások 4-nél több µop-ra fordulnak, ezeket vektorutasításoknak nevezzük.

A processzor 3 dekódert biztosít, amelyek közül az első tudja kezelni az összes 1-4 µop-ra lefordítható utasítást 1 órajel alatt, a másik kettő pedig csakis az 1 µop-ra forduló utasításokat tudja fogadni, így együtt órajelenként legfeljebb 3 utasítást tudnak lefordítani, maximum 6 µop-ot létrehozva.

A lefordított µop-ok programsorrendben a Re-Order Bufferbe kerülnek, ami továbbítja őket az ütemezőbe, amint – függőségeik figyelembevételével – rendelkezésre áll az összes bemenő paraméterük. Az ütemező ezek közül minden órajelben igyekszik mindegyik portra 1-1 µop-ot továbbítani, ahol azok végrehajtása megtörténik. Amint elkészülnek, az µop-ok eredménye újra a Re-Order Bufferbe kerül, ahonnan programsorrendben ellenőrzésre kerülnek legfeljebb 3 µop/órajel ütemben azért, hogy nem történt-e illegális művelet (például nullával való osztás vagy az olvasás/írás memóriacíme érvénytelen), majd véglegesítődnek: eredményük valóban tárolásra kerül, vagy kiváltódik a megfelelő kivétel.

Az µop-ok végrehajtása tehát spekulatív, és nem programsorrendben történik. A számítási és a memóriaolvasó műveletek lefuttatása "veszélytelen", így egymás közt korlátlanul átrendezhetőek és érvényteleníthetők, viszont a memóriába írások nem hajthatók végre ilyen módon, mivel a) a korábbi memóriaolvasásoknak mindenképp kiírás/felülírás előtt kell lefutniuk; b) az azonos címre történő memóriaírásoknak programsorrendben kell megtörténniük; c) az írásokat nem lehet visszavonni a cache-ből, illetve RAM-ból. Így az írások programsorrendben hajtódnak végre, tekintettel a programsorrendben őket megelőző memóriaolvasásokra, valamint eredményük először egy speciális pufferbe kerül (cím-adat-méret hármasonként), és a programsorrendbeli véglegesítés folyamán történik meg tényleges kiírásuk; ezáltal visszavonhatóvá válnak, és helyes sorrendbe kerülnek.

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

  • Kapcsolódó cégek:
  • Intel

Azóta történt

Előzmények

Hirdetés