RISC processzorok

1. Előzmények

A számítógépek utasítása a kezdeti időszakban, a 60-as évek elejéig, igen egyszerű és kevés számú utasításból állt és ezek kevés címzésmódot használhattak. Ez főként a technikai korlátoknak volt köszönhető. Ebben az értelemben, ezek a korai gépek csökkentett utasításkészletű, RISC gépek voltak.
1964-ben, az IBM 360-as gépcsalád bevezetésével jelent meg a kereskedelmi forgalmazású gépekben a mikroprogramozott műveleti vezérlés az utasítások végrehajtására. Ennek következtében növekedett az utasítások bonyolultsága, azaz egyre több funkciót bíztak egyetlen utasításra, emellett a használható utasítások száma is növekedett (több, mint 200-250 utasítás).
Az utasítások bonyolultsága azért növekedett különösen, mert a ROM tárolóban elhelyezett mikroprogram végrehajtása gyorsabb volt, mint az akkor használt ferritgyűrűs központi tárak által biztosított sebesség. Célszerűbb volt csökkenteni a tárhoz fordulásokat. Egy másik tényező, amely a bonyolult gépi utasítások kialakulása felé vezetett, a magasszintű programozási nyelvek széleskörű elterjedése volt. Az ezekben használt összetett utasítások miatt meg kellett alkotni ezek gépi szintű megfelelőjét, amelyeket összetett mikroprogramok, mikroeljárások segítségével valósítottak meg. Ezek segítségére különböző, bonyolult címzési módokat is kidolgoztak. Ekkor alakultak ki az összetett utasításkészletű CISC (Complex Instruction Set Computer) számítógépek.
A 70-es évek technológiai fejlődésének eredményeként megjelenő, gyors működésű félvezetős RAM tárak és cache-tárak nem tették már szükségessé a központi tárhoz fordulások erőteljes csökkentését, sőt, a kialakuló igen bonyolult mikroprogramok (gépi utasítások) lelassították a feldolgozás gyorsaságát. Emellett egyre nehezebb lett az egyre bonyolultabb mikroprogramok hibátlan előállítása, tesztelése. Ezek a tények vezettek el az egyszerűsítés szükségességének felismrése felé.
Az utasítások használatának gyakorisága vonatkozó vizsgálatok azt mutatták, hogy csak néhány utasításfajta az, ami igen sokszor használatos egy-egy programban. Felmerült a lehetősége annak, hogy a felhasználói programokat közvetlenül a mikroutasítások szintjére kellene fordítani és elhagyni az egész mikrovezérlő rendszert. Ez az elképzelés a RISC (Reduced Instruction Set Computer) processzorok alapgondolata, azaz egyszerű (mint mikroutasítások) és viszonylag kevés számú utasítás használata, elhagyva a mikroprogramot az utasítások végrehajtásából.
A legkoraibb RISC jellemzőkkel körülírható processzor, a CDC 6600-as gép kifejlesztése, a 60-as évek elején Seymour Cray nevéhez fűződik. Ugyanerre az időszakra tehető az első, ilyen típusú, gyártásba is került berendezés, az NCR 8500-as számítógép megjelnése is.
A 70-es évek közepén indult az IBM-nél egy fejlesztés melynek eredményeként 1978-ban elkészült az IBM 801-es típusú, RISC elvek szerint működő számítógép, amely igazából nem lett piaci siker. A processzor kb. 15 MHz-en ment, négy-fokozatú utasításpipeline-t és LOAD/STORE tárolási struktúrát használt. Minden utasítás és adat 32 bit hosszúságban került tárolásra. A processzor utasításkészlete 120 egyszerű utasításból állt és két címzési lehetőséggel rendelkezett. A processzroban 32 db általános célú regiszter volt.
1980 körül indult el a University fo Berkeley-n a RISC I, majd a RISC II processzorok fejlesztése. A processzor VLSI technológiával készült, 3-fokozatú pipeline feldolgozással és LOAD/STORE struktúrával. Utasításkészlete 39 utasításból állt, utasításai és adatai 32 bitesek. 138 regiszterből álló regisztertárral rendelkezett, amelynél először alkalmazták az u.n. regiszter-ablaktechnikát (register-windowing), amelyet azóta is széles körben használnak a RISC processzoroknál. A Berkeley-n kifejlesztett RISC I és II processzorok voltak struktúrálisan a SPARC processzorok elődei.
Ezzel egyidőben kezdődött a Stanford University-n a MIPS (Microprocessor without Interlocked Pipeline Stages) processzorok fejlesztése. A fejlesztésnél cél volt a hardver egyszerű volta és az utasításkészlet olyan kialakítása, amely optimalizáló fordítóprogram használatával tette lehetővé a gépi szintű program előállítását. A processzorba egy 5-fokozatú utasításpipeline-t építettek, amely egy hasonló elvű adatpipeline-nal egészült ki. Az utasításkészlet minimális volt (31 alaputasítás) és LOAD/STORE struktúra épült rá. 32 bites utasítással és adatszóval működött. A SU-MIPS processzor a mai MIPS elődje.

2. Jellemzők

Utasításkészletének főbb jellemzői:

* Kevésbé bonyolult utasítások, a felhasználói terület elemzése alapján a bonyolult utasítások elhagyása és egyszerű LOAD/STORE, műveleti és elágaztató utasítások használata.
* Kevés utasítás (<120-150) és címzési mód (2-4) használata.
* Az utasítások rögzített hosszúságúak.
* Memóriahasználatra csak 2 (LOAD és STORE) utasítás áll rendelkezésre.
* Az utasítások végrehajtásához egy gépi ciklust használnak fel.
* Az utasítások végrehajtásához nincs mikroprogram, az igen bonyolult fordítóprogram állítja elő a végső formát.

További jellemzők, előnyök, hátrányok:

* A processzor egyszerűsödése miatt, a fejlesztési ciklus, az új megoldások kidolgozása és megvalósítása lerövidül.
* Az utasítások feldolgozásának gyorsítása érdekében:
* Kevés és egyszerű szerkezetű utasítás, amely a dekódolás időtartamát csökkenti
* Huzalozott műveleti vezérles, amely kevesebb ciklusszámot igényel, mint a mikroprogramvezérelt megoldás
* A ciklusszám csökkentésére utasításpipeline alkalmazása
* Az adatelérési idők csökkentésére 3-címes regiszter-regiszter utasítások és 3-utas regisztertár-elérés (3-bus system)
* A tárolókezelés gyorsítása érdekében:
* Tárolóhierarchia kialakítása az adatforgalom optimális szervezésére, főtárbeli veremtároló hiánya
* Nagy kapacitású regisztertárak a processzor és a főtár közötti adatforgalom csökkentésére
* Külön utasítás- és adatelérési útvonal kialakítása, külön adat- és utasításcache-tár, adat – és utasítástároló alkalmazása (Harvard-struktúra)
* Az optimális gépi utasítássorozat kialakítása érdekében:
* Az utasításkészlet feladatra orientált, a kevésbé használt funkciók hiányoznak
* Bonyolult optimalizáló fordítóprogram használata, amely a magasszintű programozási nyelven leírt utasításokat a RISC processzorok nagyon egyszerű gépi utasításaira konvertálja
* A pipeline feldolgozás hatását figyelembe vevő, a „késleltetési rés”-eket kihasználó elemző eljárások beépítése a fordítóprogramba.
* A lefordított program több utasításból áll, mint a CISC processzoroké
* A védelmi lehetőségeket szoftver úton kell biztosítani.
* A VLSI áramköri technológia hatékonyabb kihasználási lehetősége:
* Több hely áll rendelkezésre az áramköri lapkán, mivel a bonyolult CISC utasítások elhagyásával, hely szabadul fel, amit a RISC processzorok esetében regisztertárak, cache-tárak elhelyezésére használnak fel (CISC processzorok esetén a vezérlő áramkörök a terület 50%-át, RISC processzorok esetén csak 6%-át foglalják el)
* Az alacsonyabb áramköri sűrűség miatt a működési sebesség magasabb lehet és a gyorsabb lapka (GaAs) használatának lehetősége.

3. Folyamatok párhuzamosítása (pipelining)

A számítógép működésének gyorsítása egyrészt az alapütemet megszabó órajel frekvenciájának növelésével, másrészt a gépen futó folyamatok párhuzamosításával oldható meg. Az órajel frekvenciája nem független az adott időszak technológiai lehetőségeitől, nem növelhető tetszőlegesen, ezert a folyamatok párhuzamosítása fontos formája a teljesítmény növelésének.
A folyamatok párhuzamosítási lehetősége azok részfázisokra való bonthatóságából adódik. A folyamatot olyan lépésekre kell bontani, amelyek mindegyike önálló részt képez és más-más erőforráshoz kapcsolódik. Így, amint felszabadul valamelyik erőforrás, azt a másik folyamat hasonló fekadatot elvégző fázisa igénybeveheti. Az egyik fázis eredménye a következő fázis induló adatát képezi. Ez az átlapolódó megoldás azt eredményezi, hogy egy-egy feldolgozási folyamat végrehajtási időtartama ugyan nem változik, de ugyanannyi idő alatt lényegesen több feladat fejezhető be. Gyakorlatilag az elemi fázisok végrehajtási idejének megfelelő időközönként fejeződik be egy-egy folyamat.


Az ilyen módon átlapolt folyamatok feldolgozásához tartozó egységek működtetése kétféle módon történhet:
* Aszinkron ütemezéssel, amely esetben az egymást követő fokozatok jelzik egymásnak elemi feldolgozási lépésük elkészültét, illetve azt, hogy készek fogadni a következő utasítást az arra az egységre előírt feladat elvégzéséhez, mindegyik egység amint befejezte tevékenységét, továbbítja a feldolgozást a következő egységnek, azaz a feldolgozás továbbhaladása folyamatos az adatcsatornán keresztül
* Szinkron ütemezéssel, amelynél az egyes fokozatok azonos időben kezdik feldolgozási lépéseiket, a feldolgozási folyamat ütemezését mindig a legtöbb időt igénybevevő egység szabja meg.
A folyamat szinkronizálásában a legnagyobb problémát az jelenti, hogy az egyes szakaszok időszükséglete igen nagy mértékben eltérhet egymástól. Ez különösen a bonyolult utasításokkal rendelkező CISC processzoroknál gond.
Az egyes szakaszok tartalmai bővebben, a RISC processzorokra jellemzően:
* Utasítás előkészítése (fetching), amely az utasításcache (I-cache) kiolvasását jelenti
* Utasítás dekódolása (decoding), a műveleti előírás elemzése, értlemezése
* Operanduscímek kiszámítása, meghatározása, a regiszter-tartalmak segítségével
* Operandusok előkészítése az adatcache-ből (D-cache)
* Művelet végrehajtása (executing), amely még általában további fázisokra bontható
* Az eredmény visszaírása az adatcache-be
* (a következő utasítás címének meghatározása)
Az utasítások folyamatos feldolgozását a legjobban a következő dolgok zavarják meg leginkább:
* a LOAD/STORE utasítások
* a feltétel nélküli, a feltételes vezérlésátadó (ugró) és ciklusutasítások
* a megszakítások, kivételek
Mivel ezek száma meglehetősen nagy, a mérések szerint az utasítások 30%-a vezérlésátadó, 40-45% a nagyrészben LOAD/STORE utasítást eredményező adatátviteli, értékadó utasítás, a feldolgozás gyorsítása szempontjából fontos, hogy ezek kezelésére megfelelő eljárásokat tervezzenek. Mindegyik esetben a folyamatos feldolgozást meg kell szakítani, fel kell függeszteni, aminek következtében a feldolgozásban lyukak keletkeznek és ezek csökkentik a pipeline hatékonyságát.
3.1. Memóriautasítások
A pipeline folyamatos működtetésének szervezése szempontjából akadályozó tényező a tárolóhoz fordulás nagyobb időigénye. Gondot okozhat az is, ha nincs külön utasítás- és adattároló (Harvard-struktúra), hogy egyidőben kell egy adatot mozgatni (LOAD/STORE utasítás miatt) és egy utasítást előkészíteni, mivel mindkét utasításfázis ugyanazt az adatutat használja.
Az egyik megoldási lehetőség a LOAD/STORE utasítást követő utasítások feldolgozásának a felfüggesztése u.n. váróciklusok (wait cycle) beiktatásával, amelynek eredményeként a pipeline-ban lyukak keletkeznek ls ha sok a tárolóhoz fordulás, akkor emiatt jelentősen lecsőkkenhet a feldolgozás hatékonysága.
Késleltetett LOAD utasítás (delayed LOAD) alkalmazására akkor kerülhet sor, ha a LOAD által betöltött adatra az utána következő utasításokban szükség lenne már. A késleltetés azt jelenti, hogy a pipeline munkájának várakozástatása helyett, a LOAD utasítást követően egy olyan utasítást kell beiktatni, amely független a beolvasandó adattól. Ez az utasítás lehet az üres utasítás (NOP) is, de akkor a hatékonyságot evvel csökkenthetjük. Ezt a problémát a fordítóprogram kell megoldja.
3.2. Elágazások
A pipeline folyamatos működtetésében a programban lévő vezérlésátadó utasítások (feltétel nélküli, feltételes ugró utasítások, ciklusutasítások) okozzák a legtöbb nehézséget. Ennek egyrészt oka az, hogy a feltétel teljesülése, az ugrási cím, csak az utasítás részbeni vagy teljes feldolgozása után válik csak ismertté, másrészt ha az ugrási címtől kell folytatni a végrehajtást, akkor az adatcsatornában lévő utasításokat törölni kell. A törléssel együtt vissza kell állítani az eredeti állapotot is.
A feltétel nélküli vezérlésátadó utasítások esetében, az egyik megoldás szerint a belépő utasításokat mindaddig várakoztatja a processzor, amíg az utasítás kiértékelése, az ugrási cím kidolgozása megtőrténik. Másik megoldás szerint, változatlanul folytatódik az utasítások betöltése az adatcsatornába és az ugrási cím meghatározása után a processzor törli a felesleges utasításokat.
A feltételes vezérlésátadó és ciklusutasítások esetében a legfontosabb teendő valamilyen módon meghatározni az ugrás várható irányát. Ezt lehet statikusan, a program fordítási fázisában kell olyan utasítássorozatot előállítani, amely legnagyobb valószínűséggel folyamatos. A dinamikus módszer futás közben vizsgálja a feltételek bekövetkeztét és az ősszegyűjtött információk alapján dönti el, hogy legközelebb bekövetkezést jósoljon vagy ne.
Az elágazásokat kezelő algoritmusok rövid összefoglalása:
* Alapmódszer: a processzor folyamatosan feltölti a pipeline-t mindaddig, amíg ki nem derül, hogy elágazási utasítás következik és az elágazást kell folytatni. Ekkor a már betöltött, felesleges utasításokat törli a pipeline-ból és elkezdi feltölteni az elágazás utasításaival.
* Leállítás(pipeline freezing): amikor nyilvánvalóvá válik, hogy, elágazási utasítást kell végrehajtani, a processzor leállítja az utasítások továbbhaladását. A leállítás történhet a dekódolási, vagy a tényleges cím kiszámítási fázisban. Ennél a módszernél az alapmódszer jobb eredményeket ad.
* Elágazás előrejelezés (branch prediction): vagy szoftver vagy hardver úton a fordítóprogram, illetve a processzor megkísérli az elágazás várható irányát jelezni. Két stratégiát különböztet meg:
* Az ugrási cím kiszámítása és a célutasítás betöltése után a processzor törli az ugró utasítás és a célutasítás közötti megkezdett utasításokat, függetlenül az elágazás tényleges bekövetkezési irányától.
* Az ugrási cím kiszámítása és a célutasítás betöltése után, a közbülső utasításokat csak akkor törli a processzor, ha az elágazás iránya valóban a feltételezett irány.
Módszerek:
* Statikus módszer: a hardver által feltételezett (beállított) módon készítik elő az elágazásokat, azaz pl. minden esetben feltételezik, hogy az ugrás nem következik be.
* Félstatikus módszer: a fordítóprogram határozza meg az elágazás legvalószínűbb irányát és ezt az utasításban elhelyezett jelzőbittel jelzi a hardver számára.
* Dinamikus módszer: a program futása közben dönti el a várható elágazási irányt a dekódolási vagy előkészítési fázis alatt az aktuális utasítás vagy az előző végrehajtások alapján.
* Utasítássorrend átrendezése: az utasítássorrend valamilyen átrendezése, széles körben alkalmazott eljárás, annak egyszerűsége miatt, valamint azért, mert fordítás időszakában alakítható ki a közel optimális feldolgozási sorrend és így a processzor teljesítménye nőhet. Módszerek:
* Késleltetett elágazás: mivel az elágazás ténye és iránya csak a feldolgozás későbbi, vagy utolsó fázisában válik egyértelművé, az elágazási utasítást közvetlenül követő helyekre más, az elágazástól függetlenül végrehajtható, vagy üres utasításokat helyezhetünk.
* Elágazás széthúzás (branch spreading): olyan processzoroknál használható, amelyek utasításkészletében külön utasítás van a feltétel vizsgálatára és beállítására és külön utasítás van az elágazásra. Addigra kell beállítani az első utasítással a feltételjelzőt, amikorra az ugró utasításnak arra szüksége van. A két utasítás közötti helyet és az ugró utasítás utáni késleltetési rést hasznos utasításokkal lehet kitölteni.
* Ciklus előrejelzés: a ciklikus programrészek elég gyakoriak, ezekben az esetekben az elágazás, azaz a visszaugrás igen nagy valószínűséggel teljesül és csak egyszer nem teljesül.
* Elágazás összecsomagolás: a CRISP mikroprocesszorokhoz dolgozták ki, nagyon hatékony, de bonyolult is. Az utasítások egy előfeldolgozással dekódolásra és kiegészítésre kerülnek a következő utasítás címével, az így kiegészített (expanded) utasítások egy cache tárba kerülnek és azt felhasználva dönt a processzor az elágazásról.
* Pipeline többszörözése: az elágazások kezelésének leghatékonyabb módja a több párhuzamos pipeline használata. Az elágazási utasításoknál mindkét irány feldolgozásra kerül, a tényleges ugrási cím kiszámítása után az ugrási iránynak megfelelő utasítások a segédpipeline-ban, míg a folyamatos továbbhaladást szolgáltató utasítások a főpipeline-ban kerülnek feldolgozásra. Ha a feltétel nem teljesül, a főpipeline utasításainak feldolgozásával folytatódik a végrehajtás és nincs késleltetés, ha a feltétel teljesül, akkor a segédpipeline tartalma áttöltésre kerül és aszerint folytatódik a végrehajtás.

4. Regisztertárak

A processzorokban egy-egy szónyi adat tárolására mindig használtak gyors működésű tárakat, hogy elkerüljék a túl gyakori memóriához való fordulást. A processzor számára egy feladat feldolgozása közben, általában a regiszterek egy része látható csak. Ennek az “ablaknak” a kialakítására születtek különbözö technikák:
* A regiszterbank (register banking) alkalmazása esetében a regisztertömb nem átlapolódó, azonos méretű részekre, u.n. “bank”-okra van felosztva. Egy-egy ilyen bank mérete 2 valamely hatványa. A processzor számára az aktuálisan használt bank kezdetét a bank-pointer (CBP=current bank pointer) jelöli ki.
* Az ablaktechnika (register windowing) alkalmazásakor a regisztertömb egy-egy azonos méretű, de átlapolható része látható és használható a processzor számára. Az “ablak” mérete mindig azonos és 2-nek valamely hatványa. Az aktuális ablak kezdetét az ablak-mutató (CWP=current window pointer) jelöli ki.
* A blokktechnika (register blocking) használatakor a regisztertömb tetszőleges méretű, átlapolható részekre van felosztva. A processzor által használt aktuális blokk kezdetét a blokk-mutató (CBP=current block pointer) jelöli ki.
* Az automatikus csere (dribble-back) technikája minimálisan két, egyenlő részre osztott, nem átlapolt blokkból álló regisztertárral dolgozik. A nem aktuális blokk tartalmát a háttérben (szabad tárciklusok alatt) kimenti a tárba, vagy visszatölti a tárból, függően a megelőző művelettől (eljáráshívás, visszatérés eljárásból). Ha az előző művelet eljárás hívás volt, akkor újabb hívásra készül fel és kimenti a nem aktuális blokk tartalmát, ha pedig visszatérés volt a megelőző művelet, akkor visszatölti az aktuális blokkot használó eljárás adatait a nem aktuális blokkba.


5. Forrás

* Cserny László: RISC Processzorok, LSI, 1995
*Minier Zsolt 541. csoport. Informatika
* http://www.heyrick.co.uk/assembler/