A Berkeley RISC egy nagy jelentőségű, az ARPA VLSI programjának keretein belül indított, fejlett nagy integráltságú mikroprocesszor létrehozását célzó kutatási projekt volt az 1980-as évek elején. A DARPA VLSI program nagy teljesítményű számítástechnikai eszközök kifejlesztését célozta meg és finanszírozta, ebbe beletartoztak a mikroprocesszorok is. A RISC projekt vezetője David Patterson volt a University of California, Berkeley egyetemen, 1980 és 1984 között – ő alkotta meg a RISC kifejezést is.[1]
A Berkeley Egyetem szomszédságában, a Stanford Egyetemen egy másik fejlesztés is folyt ebben az időben, a MIPS kutatás keretében, ez 1981-ben kezdődött és 1984-ig tartott. A Berkeley projektje annyira sikeres volt, hogy ez adta a nevét az utána következő hasonló kialakításoknak, még a MIPS is "RISC processzor"-ként ismert. A Berkeley RISC kialakítás később üzleti alapokra helyezve a SPARC processzorban realizálódott, és ez ihlette az ARM architektúrát is,[2] ami 2014-ben a legtöbb mobiltelefont hajtja. A Berkeley RISC kialakítás elemeit (pl. regiszterablakok) alkalmazzák az AMD Am29000 és az Intel i960 processzorok is.
Mind a RISC, mind a MIPS kifejlesztését az a felismerés inspirálta, hogy a programok túlnyomó többsége nem használja fel a processzorok utasításainak legnagyobb részét. Egy vizsgálatban kiderült, hogy egy Unix rendszer lefordított kódja a Motorola 68000 processzor rendelkezésre álló utasításainak mindössze 30%-át használja fel. Az m68k és hasonló processzorok áramköreinek nagy része olyan utasítások dekódolására van fenntartva, amelyeket semmi sem használ. A RISC alapötlete az volt, hogy a processzor utasításkészletében csak a (programok által) valóban felhasznált utasításokat kell megtartani és minden egyebet el kell hagyni belőle; a haszontalan utasításokat kezelő áramkörök eltávolításával felszabaduló helyet pedig a rendszer gyorsítására szolgáló áramkörök kaphatják meg.
Ennek egyik módja, hogy a RISC kialakításokban sokkal több regisztert alakítanak ki: a regiszterek igen gyors működésű kisméretű memóriák, melyeket a processzor elhanyagolható költséggel / időtartam alatt képes elérni, ellentétben a központi memóriával, amelynek az elérése több órajelciklust is igényelhet. Ha egy processzor sok regisztert tartalmaz, és biztosított, hogy a fordítóprogramok valóban fel is használják azokat, akkor a programoknak sokkal gyorsabban kell futniuk. Egy ilyen kialakításban a processzor sebességét leginkább az órajele határozza meg, mivel kevesebb időt kell töltenie a memóriahozzáférésekre való várakozással. Azonos tranzisztorszám mellett a RISC kialakítás teljesítménye elméletileg meghaladja a hagyományos kialakítású CPU teljesítményét, remélhetőleg sokkal.
Az elgondolás egyik hátránya abból következik, hogy a megszüntetett utasítások általában több részutasítást hajtanak végre egyszerre. Például a tradicionális kialakítások ADD
utasítása általában több stílusban (változatos címzési módokkal) használható, az egyikben pl. az utasítás két regiszterben tárolt számot ad össze és az eredményt egy harmadikban helyezi el, egy másikban az összeadandókat a fő memóriából veszi és az eredmény egy regiszterbe kerül, stb. A RISC kialakításokban az utasításoknak csak egyetlen használati módja van, így az ADD
utasítás mindig regisztereket használ az összes operandus tárolására. Ezáltal a programozók külön utasításokat kénytelenek használni például az értékek memóriából való betöltésére és azok visszaírására, emiatt a RISC típusú programok kevésbé „tömörek”, több helyet foglalnak el a tárban és az adathordozókon.
A drága memóriák korában ez valódi gondot okozott, különösen mivel a memóriák sebessége sokkal lassabb volt, mint a processzoroké. Mivel a RISC design ADD
utasítása valójában négy műveletet igényel (két betöltés, egy összeadás és egy kiírás), a gépnek sokkal több memóriahozzáférést kéne végeznie az extra utasítások beolvasásával, ami jelentősen lassítaná a működést. Ezt bizonyos mértékben ellensúlyozta az a tény, hogy az újabb kialakításokban az akkoriban sokkal nagyobbnak számító 32 bites utasításszót alkalmazták, ami lehetővé teszi a kis konstansok / állandó értékek közvetlenül az utasításba való kódolását, azok külön betöltése helyett. Továbbá, egy művelet eredményeit gyakran a rákövetkező műveletek használják fel, így a memóriába való kiírás elhagyásával és az eredmény regiszterben való tárolásával a programok mérete nem nőtt meg jelentősen, azonban elméletileg sokkal gyorsabban kell futniuk. Például, egy utasítássorozatnak, amely matematikai műveletek sorát végzi el, mindössze néhány adatbetöltésre van szüksége a memóriából, míg a felhasznált számok többsége vagy magában az utasításban kódolt állandók, vagy a regiszterekben tárolt átmeneti értékek lehetnek. Úgy is értelmezhető, hogy ebben a technikában egyes regiszterek a memóriahelyek „árnyékaként”, tartalmának másolataként szolgálnak, tehát csak a megfelelő memóriahelyek „beugró” helyettesítői, amíg az utasítássorozat meg nem határozza a végső értékeket.
A hétköznapi megfigyelők számára nem volt világos, hogy a RISC koncepció vajon növelni fogja-e a teljesítményt vagy esetleg rontani. Ezt csak gyakorlati szimulációval lehetett kideríteni. A tesztek elvégzése után az eredmények egyértelműek voltak. Minden teszt és szimuláció azt mutatta, hogy az új kialakítás teljesítménye általános téren hatalmasan megnőtt.
A RISC és a MIPS tervezetek eltértek/nek a regiszterek használatában. A MIPS egyszerűen nagy számú regisztert alkalmaz, és a fordítóprogramra – vagy az assembly programozókra – bízza ezek optimális kihasználását. A RISC ezzel szemben hozzáadott áramkörökkel segíti a fordítót. A RISC a regiszterablak-koncepciót alkalmazza, amelyben a teljes regisztertömb blokkokra van osztva, a processzor csak az aktuális „ablakba” eső regiszterekkel dolgozhat és a blokkok helye könnyen változtatható. A fordítóprogram az állandóan látható globális blokkot és egy változó helyű blokkot használ, ami a lokális változók tárolására szolgál.
A cél az egyik rendkívül gyakori utasítás, az eljáráshívás használatának végletes leegyszerűsítése volt, tehát ezek használatának megkönnyítése a fordítóprogramok számára. Majdnem minden programozási nyelvben ismert az „aktivációs rekord” avagy „veremkeret” fogalma – minden procedúrához, moduláris végrehajtási egységhez, tartozik egy hívási cím, a modulnak átadott kiinduló adatok és a modul által visszaadott eredmények tárolására szolgáló területek (másként: a kezdőcím, bemeneti és kimeneti paraméterek).[3] Az esetek legnagyobb részében ezek az adatstruktúrák – keretek – kicsik, tipikusan három vagy kevesebb bemeneti paramétert és egy vagy semennyi kimeneti paramétert tartalmaznak, esetenként a kimenet a bemeneti paraméterek helyére kerül. A Berkeley kialakításban a regiszterablak néhány regisztert fog össze, annyit, amennyi az esetek többségében elegendő egy eljárás teljes veremkerete számára.
Ezt a technikát felhasználva az eljáráshívás igen egyszerű és rendkívül gyors. Az új regiszterblokk – regiszterablak – beállításához egyetlen művelet hívása szükséges, ezután az ablak „alsó részében” az eljárásnak átadott paraméterekkel, a program az eljárás címére ugrik. A visszatéréskor az eredmények ugyanoda kerülnek, és az eljárás befejeződik (kilép). A regiszterablakok a úgy vannak kialakítva, hogy átfedések vannak közöttük, így a visszaadott értékek egyszerűen „megjelennek” a hívó folyamat ablakában és ennek során nem történik adatmozgatás. Így az általános eljárásnak nem kell használnia a fő memóriát, ami gyorsítja a működést.
Ennek a módszernek a hátulütője, hogy nagyszámú lokális változó kezelése problémát okoz, valamint túl kevés paraméter / változó használata esetén a módszer fölöslegesen pazarolja a drága regisztereket. A kialakításban a regiszterablakok száma véges, tegyük fel, hogy egy ilyen kialakításban nyolc; ekkor az eljáráshívások ilyen mélységig ágyazhatók egymásba, mielőtt az ablakkezelő mechanizmus elérné a határait; amint a rendszer aktiválta az utolsó ablakot, nem lehet új ablakot nyitni a további beágyazott hívásoknak. Ha viszont az eljáráshívások csak néhány szint mélységig vannak egymásba ágyazva, akkor az ablakváltás nem éri el a mélyebb szinteken lévő regisztereket, és azok így teljesen használatlanul maradnak, kárba vesznek.
A fordítóprogramok területén végzett kutatás eredményei a Stanford projekt fejlesztőit arra késztették, hogy teljesen elvessék a regiszterablak-koncepciót, ehelyett azt az elvet követték, hogy egy hatékony fordítóprogram jobban ki tudja használni a regisztereket, mint egy fix hardveres rendszer (ugyanez az érvelés alkalmazandó az okos assembly nyelvű programozókra is.)
Az első kísérlet a RISC koncepció megvalósítására a Gold nevű projekt volt. Ennek tervezése 1980-ban kezdődött az egyetemen, a „VLSI tervezés” tantárgy részeként, ám az akkor még túl bonyolult tervek összeomlasztották szinte az összes létező tervezőeszközt. A tervezőcsapat kénytelen volt jelentős időt fordítani az eszközök (tervezőprogramok) feljavítására vagy újraírására, és még az új eszközökkel is majdnem egy órába telt egy teljes terv elkészítése egy VAX-11/780-as gépen.
A végső, RISC I-ként ismert tervezetet az ACM ISCA szimpóziumán publikálták 1981-ben.[4] Ez 44 500 tranzisztorból áll, 31 utasítást implementáltak benne, regisztertára 78 db. 32 bites regisztert tartalmaz. Ez lehetővé teszi hat regiszterablak használatát (a főprogrammal együtt), ahol egy ablak 14 regisztert tartalmaz, amit 18 globális regiszter egészít ki. A program mindig az r0-tól r31-ig számozott regisztereket látja.[5] A vezérlő és utasításdekódoló rész csak 6%-ot foglal el a lapkán, miközben a kor tipikus processzorainál ez az arány 50% körül van. A legnagyobb helyet a regisztertár foglalja el.[5]
A RISC I kétfokozatú utasítás-futószalaggal rendelkezett, a sebesség további fokozása érdekében, azonban a modernebb kialakításokra jellemző komplex utasítás-átrendezés hiányzott belőle. Emiatt a feltételes elágazások problémát okoztak, mert a fordítóprogramnak ki kellett töltenie a feltételes elágazást követő utasítás helyét (az ún. elágazási várakoztatási rést) valamilyen „biztonságosnak” ítélt utasítással (pl. egy olyannal, ami nem függ a feltétel kiértékelésétől). Gyakran az egyetlen elfogadható megoldás ebben az esetben a NOP
utasítás. Számos későbbi RISC típusú architektúra még mindig megköveteli az elágazási várakoztatási rés figyelembevételét.
Egy hónapnyi kiértékelés és debuggolás után a terveket elküldték az innovatív MOSIS szolgáltatóhoz 2 μm-es (2000 nm-es) folyamattal történő gyártásra, 1981. június 22-én. Különféle okok miatt a maszkokat négy alkalommal újra kellett gyártani, és a működő példányokat tartalmazó ostyák (wafer) csak 1982 májusában érkeztek vissza Berkeleybe. Az első működő RISC I „számítógép” – valójában csak egy tesztkártya – június 11-én indult el. A tesztek során a csipek a vártnál alacsonyabb teljesítményt mutattak. Általában egy utasítás végrehajtása 2 μs-ot vett igénybe, ami a tervekben kitűzött 0,4 µs-os (400 ns) végrehajtási idő ötszöröse volt. Ennek a jelenségnek a pontos oka a mai napig nem ismert, ugyanakkor az átfogó tesztelés alatt kiderült, hogy bizonyos utasítások a várt sebességen futnak, ami azt sugallja, hogy a probléma oka fizikai, nem pedig logikai.
Ha az eszköz elérte volna a teljes tervezett sebességét, a teljesítménye kiváló lett volna; a 4 MHz-es RISC I, az 5 MHz-es 32 bites VAX 11/780 és az 5 MHz-es 16 bites Zilog Z8000 processzorokon futtatott kisebb programok szimulációi ezt világosan megmutatták. A programméret kb. 30%-kal nagyobb volt, mint a VAX gépen, de nagyon közel járt a Z8000-éhoz, ami azt az állítást erősíti, hogy a CISC típusú kialakítások magasabb kódsűrűsége a valóságban nem is olyan jelentős. Az átfogó teljesítmény illetően a RISC I kétszer olyan gyors volt, mint a VAX, és négyszer gyorsabb a Z8000-nél. Még érdekesebb, hogy a programok működése során a memóriahozzáférés összmennyisége közel ugyanakkora volt, mert a nagy regisztertár drámaian megnövelte annak az esélyét, hogy a kívánt operandus már a csipen, a regisztertárban van.
Fontos ezt a teljesítményt a környezetében szemlélni. Még ha a RISC kialakítás lassabban is futott, mint a VAX, ez semmit nem von le a kialakítás fontosságából. Bebizonyosodott, hogy a RISC tervezési elv alapján igazi 32 bites processzor gyártható, valódi szilíciumcsipen, egy már abban az időben is kiöregedett gyártási technológiát alkalmazva. A tradicionális kialakítások ezt egyszerűen nem tudták megtenni; mivel a csip felületének nagy része a dekódoló logika céljait szolgálta, egy igazi 32 bites design, mint pl. a Motorola 68020, újabb gyártástechnológiát igényelt ahhoz, hogy a gyakorlatban is használható legyen. Ugyanazt a technológiát használva a RISC I teljesítménye nagymértékben felülmúlta volna a versenytársait.
Miközben a RISC I megvalósítása késlekedett, a Berkeleyn a munka folytatódott és az új Blue tervezet felé fordult. A Blue tervezése a Gold-énál lassabban haladt, két okból is: nem volt akkora nyomás, most, hogy a Gold a gyártósorra került, és az osztályok, tehát a tervezőcsapat összetétele is sokat változott közben. A lassabb tempó lehetővé tette számos új tulajdonság hozzáadását, ami jelentősen javította a kialakítás végső teljesítményét.
A legnagyobb különbség az egyszerűbb gyorsítótár-áramkör volt, amelyben egy vonallal kevesebbet (3 helyett 2-t) használtak fel egy bit tárolására és ez drámaian összezsugorította a regisztertár méretét. A változtatás szorosabb időzítést követelt meg a belső síneken, és az eszköz más részeit is fel kellett gyorsítani, hogy megfeleljenek a követelményeknek, de ez viszonylag kis ár volt az előnyökhöz képest.
Az új tervekből fakadó megtakarítások félelmetesek voltak. Míg a Gold összesen 78 regisztert tartalmazott 6 ablakban, a Blue 138 regisztert 8 ablakba beosztva, ahol az ablakok mérete 22 regiszter és ezekhez 10 globális regiszter társul. A regisztertömb ilyen bővítése nagymértékben megnöveli az esélyt, hogy az adott procedúra el tudja helyezni az összes lokális változóját a regiszterekben, és a procedúrahívások beágyazási mélysége is növekszik. A nagyobb regisztertár mégis kevesebb tranzisztorral volt megvalósítva, és a Blue végső terveiben, ami a RISC II néven került gyártásba, az egész RISC utasításkészletet mindössze 39 000 tranzisztorral valósították meg.
Egy másik nagy változtatás volt, hogy bevezettek egy „utasításformátum-kiterjesztőt”, ami láthatatlanul felkonvertálta a 16 bites utasításokat eredeti 32 bites formátumukra. Ez lehetővé tette, hogy kisebb, tipikusan egyoperandusú vagy operandus nélküli utasításokat, mint pl. a NOP
, rövidebb 16 bites formában tároljanak a memóriában, és két ilyen utasítást egyetlen gépi szóba lehetett csomagolni. Az utasításokat a kiterjesztő logika észrevétlenül 32 bites utasításokká konvertálja, mielőtt elérnék az ALU-t, ami azt jelentette, hogy a logikai magot nem kell átalakítani. Ez az egyszerű technika meglepő módon 30%-os javulást okozott a kódsűrűségben, és ezáltal az egyébként megegyező programok a Blue-n gyorsabban futottak, mint a Gold-on, a csökkentett számú memóriahozzáférés miatt.
A RISC II sokkal sikeresebbnek bizonyult szilíciumon, és a tesztek során túlteljesített majdnem minden létező korabeli miniszámítógépet, szinte minden feladatban. Például a teljesítmény 85% VAX sebességtől 256%-ig terjedt, tehát a RISC II gyakran a VAX sebességének kétszeresén futott. A RISC II teljesítményét összemérték a híres Motorola 68000-ével is, amelyet akkoriban a legjobb kereskedelmi célú csipmegvalósításnak tartottak, és a RISC II azt is felülmúlta 140% és 420% közötti mértékben.
Az eredeti RISC kialakításon folyó munka a RISC II-vel véget ért, de a koncepció maga tovább élt a Berkeleyn. Az alapvető mag újrahasznosításra került a SOAR projektben 1984-ben, ami tulajdonképpen egy Smalltalk futtatására átalakított RISC (hasonlóan ahhoz, ahogy a RISC a C nyelvű programokat támogatta), és később a hasonló VLSI-BAM, amely a PROLOG futtatását támogatta. Egy másik erőfeszítés volt a SPUR, ami nem más, mint egy komplett 32 bites munkaállomás építéséhez szükséges teljes csipkészlet.
A RISC nem erről a leghíresebb, de nagyon nagy jelentőségű az a tény, hogy a RISC szolgált alapul a Sun Microsystems kereskedelmi célú SPARC processzora terveinek. A SPARC volt az első processzor, amely tisztán megmutatta a RISC koncepció erejét; mikor ezek a processzorok megjelentek a piacon az első SPARCstation munkaállomásokban, minden terméket leköröztek a piacon. Ennek következtében majd' minden Unix-szállító sietett kialakítani a saját RISC verzióját, ami az olyan típusokhoz vezetett, mint a DEC Alpha és PA-RISC, míg az SGI felvásárolta a MIPS Computer Systems vállalatot. 1986-ra a nagy csipgyártók többsége is követni kezdte ezt az irányzatot, és olyan terveken kezdett dolgozni, mint a Motorola 88000, Fairchild Clipper, AMD 29000 és a PowerPC.
A redukált utasításkészlet elvéhez és amellé kifejlesztett technikákat adaptálták a tradicionális „komplex” x86 architektúra későbbi, nagyobb teljesítményű változataiba is. A mai processzorok tranzisztorszámának legnagyobb részét a nagy gyorsítótárakra fordítják, emellett ezekben sok fokozatú utasítás-futószalagokat, szuperskalár utasításkiküldést, elágazásjóslást és más modern technikákat alkalmaznak, amik az utasításkészlet-architektúra (ISA) figyelembevétele nélkül alkalmazhatók (tkp. a technológiák nem ISA-hoz kötöttek). Az utasításdekódolás céljaira fordított szilíciumfelület a modern x86 megvalósításokban százalékában elég kicsi, így ez a megkülönböztetés a „komplex” és RISC processzorkialakítások között elmosódottá vált és elvesztette jelentőségét.
Ez a szócikk részben vagy egészben a Berkeley RISC című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.