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.
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 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, 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.
A RISC koncepció 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, melynek 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ória-hozzá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, melyben 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). 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 ú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.
A módszer 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.)
RISC I
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. Ez 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. 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.
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. A jelenség 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.