computer architecture

Üdvözlöm, Ön a computer architecture szó jelentését keresi. A DICTIOUS-ban nem csak a computer architecture szó összes szótári jelentését megtalálod, hanem megismerheted az etimológiáját, a jellemzőit és azt is, hogyan kell a computer architecture szót egyes és többes számban mondani. Minden, amit a computer architecture szóról tudni kell, itt található. A computer architecture szó meghatározása segít abban, hogy pontosabban és helyesebben fogalmazz, amikor beszélsz vagy írsz. Acomputer architecture és más szavak definíciójának ismerete gazdagítja a szókincsedet, és több és jobb nyelvi forráshoz juttat.

Főnév

computer architecture (tsz. computer architectures)

  1. (informatika) számítógép-architektúra

A számítógép-architektúra a számítógépek belső felépítését, működését, valamint a hardver és szoftver közötti kapcsolatot vizsgálja. Ez az informatika egyik alapköve, amely megmutatja, hogyan hajtódnak végre az utasítások a processzorban, hogyan áramlik az adat, és hogyan működik a memória.



🧱 Számítógép-architektúra fő komponensei

Főegység Funkció
Központi egység (CPU) Utasítások értelmezése, végrehajtása
Memória (RAM) Adatok és programok ideiglenes tárolása
Tárolók (HDD, SSD) Tartós adattárolás
Buszrendszer Adatok továbbítása az alkatrészek között
I/O egységek Be- és kimeneti eszközök (billentyűzet, kijelző stb.)



🧠 A Neumann-architektúra (klasszikus modell)

A legtöbb modern számítógép a Neumann János által megfogalmazott elvek szerint működik:

  1. Ugyanaz a memória tárolja az adatokat és a program utasításait
  2. Az utasításokat sorrendben hajtja végre
  3. Az aritmetikai egység (ALU) végzi a számításokat
  4. Központi vezérlőegység (CU) irányítja a működést
  5. Az adatokat és utasításokat a buszok mozgatják



⚙️ CPU belső felépítése

  • ALU (Aritmetikai és logikai egység) – műveletek végrehajtása (pl. összeadás, AND)
  • CU (Vezérlőegység) – utasítások értelmezése, vezérlés
  • Regiszterek – kis méretű, gyors belső memória (pl. akkumulátor, PC, IR)
  • Órajel (clock) – ütemezés (Hz, GHz)



🔄 Utasítás-végrehajtási ciklus (Fetch–Decode–Execute)

  1. Fetch – Az utasítás beolvasása a memóriából
  2. Decode – Az utasítás értelmezése
  3. Execute – A művelet végrehajtása az ALU-val



💡 Modern CPU fejlesztések

  • Pipelining – több utasítás párhuzamos végrehajtása, külön fázisokban
  • Cache memória – gyors elérésű memória (L1, L2, L3)
  • Multicore – több processzormag egy chipen
  • Hyper-threading – logikai magok, párhuzamos végrehajtás illúziója
  • Speculatív végrehajtás – utasítások előrehozása



📊 Memóriahierarchia

Szint Példa Sebesség Méret Ár
Regiszter CPU-n belül Nagyon gyors Nagyon kicsi Nagyon drága
Cache (L1-L3) CPU mellett Gyors Kicsi Drága
RAM (főmemória) DRAM Közepes Közepes Közepes
SSD/HDD Tárhely Lassú Nagy Olcsó



🔌 Buszrendszerek típusai

  • Adatbusz – adatokat továbbít
  • Címbusz – megadja, hova menjen az adat
  • Vezérlőbusz – utasításokat, szinkronizálást biztosít



🧠 Utastáskészletek (ISA – Instruction Set Architecture)

Az ISA a szoftver és hardver közötti interfész, ami meghatározza:

  • milyen utasításokat tud a CPU végrehajtani
  • milyen regiszterek, címzési módok állnak rendelkezésre

Példák:

  • x86 – Intel/AMD processzorok (CISC – komplex utasítások)
  • ARM – mobil eszközök (RISC – egyszerűbb, gyors utasítások)
  • RISC-V – nyílt forráskódú ISA



🧩 Különleges architektúrák

  • GPU (Graphics Processing Unit) – sok párhuzamos művelet, képfeldolgozás, gépi tanulás
  • DSP (Digital Signal Processor) – jelek gyors feldolgozása (hang, kép)
  • FPGA (Field-Programmable Gate Array) – hardverprogramozható eszközök



🧪 Példa: egyszerű ALU művelet (összeadás)

Regiszter A: 00000101 (5)
Regiszter B: 00000011 (3)
ALU művelet: A + B = 00001000 (8)

📚 Hol tanulhatod?

  • Számítógépes architektúra tantárgy az informatikai/mérnöki képzéseken
  • Fontos alapja: Assembly nyelv, digitális logika, mikroprocesszorok

Számítógép-architektúrák összefoglaló

Információ reprezentáció: számrendszerek (egész, fix, lebegőpontos)

  • Számrendszerek: A számítógépek bináris (kettes) számrendszerben dolgoznak, de gyakran használunk nyolcas és tizenhatos jelölést is. Egy N bites bináris szám 2^N különböző értéket reprezentálhat. A kettes komplemens a legelterjedtebb mód a negatív egészek ábrázolására – előnye, hogy az összeadás és kivonás azonos áramkörrel megoldható, nincs külön hardver a negatív számokra. A negatív szám előállítása kettes komplemensben: bitenkénti negálás után +1 hozzáadása.
  • Egész számok (egész/fixpontos ábrázolás): Az egész szám kettes komplemens formában történő tárolása esetén az első (legmagasabb helyiértékű) bit jelzi az előjelet (0 = pozitív, 1 = negatív). A pozitív számok hagyományos bináris formában, a negatívok kettes komplemensben tárolódnak. Fixpontos (rögzített pontos) ábrázolásnál a bináris pont helye rögzített: adott számú bit képviseli az egész és tört részt. Például Q15 formátum esetén 1 bit az előjel, 15 bit a tört (frakció) rész – ezzel korlátozott tartományban, de adott tizedes pontossággal ábrázolhatunk valós számokat.
  • Lebegőpontos számok: A lebegőpontos ábrázolás a valós számokat egy előjeles mantissza és egy exponens segítségével reprezentálja. A mantissza rögzített számú értékes számjegyből áll, az exponens pedig skálázza azt egy alap hatványaként (az alap tipikusan 2 a bináris számítógépeknél). A bináris lebegőpontos szám formája: ± mantissza × alap^exponens. A lebegőpontos formátum előnye a fixpontossal szemben a hatalmas ábrázolható tartomány, cserébe a pontosság (felbontás) korlátozott. A szabványos lebegőpontos formátum az IEEE 754, pl. 32 bites (egyszeres pontosságú) lebegőpontos szám: 1 bit előjel, 8 bit kitevő (excess-127 kóddal tárolva), 23 bit mantissza (a normálizált formátum rejtett 1-esével együtt 24 bites pontosság).
  • Példa: (8 biten), míg kettes komplemensben: . Lebegőpontos példában az érték 32 bites IEEE 754 formátumban: előjel , kitevő (excess-127 formában), mantissza . (Itt a kitevő binárisan , a mantissza tárolt mezője pedig ).

Nem-numerikus információábrázolás, hibakezelés (pl. Hamming-kód)

  • Nem numerikus adatok: Ide tartozik a szöveg (karakterek), logikai értékek (Boole-féle igaz/hamis), grafikus szimbólumok (képpontok, alakzatok), továbbá a vezérlő- és címinformációk. A szöveges adatok kódolására szabványokat használnak: pl. ASCII kód (7 bites alap kódtábla, kiterjesztve 8 bitre 256 karakterig), vagy Unicode/UTF-8 (változó hosszúságú kódolás, amely gyakorlatilag minden nyelv karaktereit támogatja). Egy 7 bites ASCII kód pl. a nagybetűk, kisbetűk, számjegyek és néhány írásjel ábrázolására elegendő (128 karakter), míg az UTF-8 több byte-on tárolja az egyes karaktereket, így sok ezer különböző jel is ábrázolható.
  • Adathiba detektálás és korrekció: A digitális kommunikációban és tárolásban redundáns bitek hozzáadásával biztosítható a hibák felismerése/javítása. Egyszerű módszer a paritásbit alkalmazása: egy extra bit jelzi, hogy a küldött adatbit-sorozatban páros vagy páratlan számú 1-es van-e. Például páros paritás esetén a paritásbitet úgy választják, hogy az összes 1-es bit száma páros legyen. A paritásbit egybitnyi hibát képes detektálni (ha a paritás sérül, hiba történt), de nem tudja megmondani, melyik bit volt rossz, és két hibát nem vesz észre.
  • Hamming-kód: Több redundáns bit alkalmazásával már nemcsak a hiba megléte, hanem helye is azonosítható, így egy bitnyi hiba javítható is. A Hamming-kód olyan hibajavító kód, amely adott számú adatbithez megfelelő számú ellenőrző (paritás) bitet ad hozzá. Például a (7,4) Hamming-kód 4 adatbitet továbbít 3 redundáns bit kíséretében. Az ellenőrző bitek különböző bitcsoportok paritását figyelik, így ha 1 bit elromlik, a paritásmintázatából következtetni lehet a hibás bit pozíciójára, és az javítható. (Az ún. SEC-DED kódok egyetlen hibát javítanak és kettőt képesek jelezni – Single Error Correction, Double Error Detection.) A Hamming-kód példa: 4 adatbit (d1,d2,d3,d4) esetén 3 ellenőrző bit (p1,p2,p3) kerül hozzájuk, ezek értékét úgy választjuk, hogy bizonyos bithelyi paritások (pl. minden páros sorszámú bit stb.) nullára jöjjenek ki. Ha egy bit megváltozik, a paritások mintázata pontosan meghatározza, melyik bit a hibás, így az javítható.

Neumann és Harvard architektúrák összehasonlítása

  • Neumann-architektúra (von Neumann elv): A klasszikus Neumann-elvű számítógép egy közös memóriában tárolja az adatokat és a program utasításait. Ugyanazon adatúton (buszon) keresztül olvassa a CPU az utasításokat és mozgat adatokat is. Ennek a modellnek az előnye az egyszerűség és rugalmasság – a program módosítható a memória tartalmának átírásával, nincs elkülönült programtár. Hátránya a híres Neumann-csűk (Neumann-bottleneck): mivel egy buszt használ, egyszerre egy időben nem lehet utasítást betölteni és adatot olvasni/írni, a memória-hozzáférés korlátozza a sebességet. Emiatt a CPU gyakran várakozik a memória műveletekre. Továbbá a közös tár miatt elvileg fennáll a veszélye, hogy egy hibás program az utasításokat (kódot) felülírja (például rossz mutató miatt), ami rendszerhibát okozhat.
  • Harvard-architektúra: Olyan számítógép-felépítési elv, ahol a programkód és az adat külön memóriában, külön buszrendszeren helyezkedik el. Az utasítások és adatok fizikailag elkülönített útvonalakon jutnak a processzorhoz. Ennek következtében párhuzamos adatforgalom valósítható meg: a CPU egyidejűleg tud utasítást fetch-elni az utasításmemóriából és adatot olvasni/írni az adattárba (így kiküszöbölhető a Neumann-csűk egy része). A Harvard-modell eredetileg a Harvard Mark I elektromechanikus számítógépnél jelent meg (ott lyukszalag tartalmazta a programot, az adatok pedig regiszterekben voltak). Előnyei: nagyobb teljesítmény párhuzamos utasítás-/adatelérés révén, továbbá az elkülönítés biztonsági szempontból is előny (a programkód nem könnyen írható adatként, nehezebb önmodifikáló vagy vírus kódokat létrehozni). Hátrányai: a memóriák különválasztása merevebbé teszi a rendszert – pl. ha egy beágyazott rendszerben az utasításmemória tele van, de adatmemória bőven van még, a program nem bővíthető tovább, mert nem használhatja az adatmemória helyét. Továbbá a különböző memória-technológiák kezelése egy chipen belül bonyolultabb lehet, és a magas szintű programozási nyelvek sem támogatják közvetlenül a kód mint adat kezelését (speciális utasítások vagy assembly kell hozzá). Emiatt sok általános célú CPU inkább Neumann-elvű fő memóriát használ.
  • Modern rendszerek: Valójában a legtöbb mai processzor vegyes elvet követ: modifikált Harvard-architektúra. A CPU-n belül, a gyors elsőszintű cache-ek szintjén gyakran elkülönül az utasítás- és adatcache (Harvard jelleg), míg a főmemória egységes címterű (Neumann jelleg). Ez ötvözi az előnyöket: a processzor belsőleg párhuzamosan képes utasítást és adatot cache-ből kiszolgálni, de a memória-menedzsment és programozás szempontjából egy memóriatérrel dolgozunk.

ALU felépítése és lebegőpontos műveletek (összeadás, kivonás, szorzás, osztás)

  • ALU (Arithmetic Logic Unit): Az ALU az a processzoron belüli kombinációs-logikai egység, amely az aritmetikai (összeadás, kivonás, szorzás, osztás) és logikai (ÉS, VAGY, XOR, NOT stb.) műveleteket végzi. Az ALU tipikusan két bemeneti operandussal és egy kimenettel rendelkezik, a művelet típusát pedig az utasítás határozza meg (az ALU vezérlő jelei). Az ALU-ban találhatók az összeadók, amelyek a legtöbb művelet alapját adják. A műveleti eredményekről az ALU állapotjelző biteket (flag-eket) szolgáltat a vezérlőegységnek, pl. carry/borrow (átevitel), overflow (túlcsordulás), zero (nulla eredmény), negatív eredmény stb., melyeket feltételes utasítások (pl. ugrások) használnak.
  • Lebegőpontos műveletek végrehajtása: A lebegőpontos műveletek bonyolultabbak az egész műveleteknél, gyakran külön FPU (Floating Point Unit) egység végzi őket. Lebegőpontos összeadás/kivonás: a két operandus kitevőit először egyenlővé kell tenni (azaz a kisebb kitevőjű szám mantisszáját jobbra kell shiftelni, amíg az exponensek egyeznek). Ezután a mantisszákat összeadjuk/kivonjuk normál egész összeadókkal. Az eredményt normalizálni kell: ha a mantissza kicsúszott a megengedett tartományból (≥2 vagy <1, normálizált alakban), akkor eltoljuk (és korrigáljuk az kitevőt). Az utolsó lépés a kerekítés, mivel a mantissza bitszélessége véges. Például összeadásánál először a második számot át kell alakítani formára (exponense 3 lett), majd a mantisszák összeadása: , amit normalizálva lesz (ha 5 bites mantisszát feltételezünk). Az FPU ezen lépéseket hardveresen pipelinnel valósítja meg.
  • Lebegőpontos szorzás: A mantisszákat szorozzuk össze (ami kb. kétszeres bitmélységű eredményt adhat, ezt is normalizálni/kerekíteni kell), míg az exponenseket összeadjuk (figyelembe véve az elfogadott bias kódolást). Az előjel az operandusok előjelbitjeinek XOR-a. Például , ahol a mantissza-szorzás és kitevő-összegzés adja az eredményt. A lebegőpontos szorzás relatív egyszerű, mert nem kell az operandusok exponenseit igazítani (csak összeadni), legfeljebb a végeredmény mantisszáját normalizálni.
  • Lebegőpontos osztás: Az osztás a szorzás fordítottja: a mantisszákat osztjuk (amihez normalizálás szükséges, pl. ha az osztó mantisszája nagyobb mint az osztandóé), az exponenseket kivonjuk (osztandó exponens mínusz osztó exponens). Az előjelnél XOR szabály érvényes. Például binárisan: osztva = (ami 3.0, persze megfelelő bináris kerekítéssel). Az FPU az osztást tipikusan egy speciális iteratív áramkörrel vagy a szorzás reciprokkal történő kiváltásával (reciprokszorzás, pl. Newton–Raphson iterációval) végzi, mivel a direkt osztóáramkör bonyolult és lassabb.
  • Megjegyzés: A modern processzorok a lebegőpontos számokat általában IEEE 754 formátumban kezelik (32 bites float, 64 bites double, stb.), a műveletek eredményét pedig e szabvány szerint kerekítik (alapértelmezésben a legközelebbi ábrázolható számra kerekítve, „round to nearest, even” szabály). Külön figyelmet igényelnek a speciális értékek: , (túlcsordulás), NaN (Not a Number – értelmezhetetlen eredmények), és a denormál számok (nagyon kicsi, normálizálatlanul tárolt értékek).

Összeadó, kivonó áramkörök: FA, RCA, LACA, FS

  • Félösszeadó és teljes összeadó: Az összeadó áramkörök alapvető építőelemei a félösszeadó (HA – Half Adder) és a teljes összeadó (FA – Full Adder). Egy félösszeadó két egybites bemenetet (A és B) ad össze, eredménye egy összeg bit (S) és egy átvitel bit (C). Például esetén S=0, C=1 (1+1=10₂). A teljes összeadó már figyelembe veszi az előző pozícióból érkező átvitel-bementet is (Cin), így három bemenetet (A, B, Cin) és két kimenetet (S – összeg, Cout – kimenő carry) tartalmaz. Két félösszeadóból és egy VAGY kapuból építhető fel: először A és B összege ad egy rész-összeget és első carry-t, majd ezt a rész-összeget adjuk össze Cin-nel a második félösszeadóban. A teljes összeadó lehetővé teszi tetszőleges hosszúságú bináris számok összegzését úgy, hogy az egyes bithelyek teljes összeadóit sorba fűzzük (az alacsony helyiértékű FA Cout-ja a következő FA Cin bemenete).
  • Ripple Carry Adder (RCA – átvitel továbbterjesztő összeadó): N darab bites szám összeadásához N darab teljes összeadót láncolunk sorba: az LSB helyiértéknél lévő FA Cin bemenete a nulla (vagy egy esetleges alacsonyabb rendű előző összeadás carry-je), majd minden FA a saját Cout kimenetét továbbadja a következő, eggyel magasabb bitű FA Cin-jére. Ezt a felépítést nevezzük ripple carry összeadónak, magyarul hullámzó átvitelű összeadó (a carry bitek egymás után „fodrozódva” terjednek át a következő pozíciókra). Előnye a strukturális egyszerűség, hátránya, hogy lassú, mivel a legfelső bit eredménye megvárja, míg az összes alatta lévő bitnél „végighullámzik” az átvitel. A késleltetés lineárisan nő a bites szélességgel (O(N)). Egy 64 bites ripple-carry összeadónál például worst-case a legalacsonyabb helyiértékről induló átvitel 63 kapuláncon halad át, mielőtt a legfelső bitnél eredményt kapnánk.
  • Look-Ahead Carry Adder (LACA – hordozó előretekintéses összeadó): Célja az összeadás felgyorsítása a carry bitek párhuzamos kiszámításával. Ehhez minden bithelyen definiálnak propagate () és generate () jeleket: , ha az -edik pozíció továbbítja az átvivőt (azaz ha vagy 1, akkor egy esetleges korábbi carry át fog menni ezen a biten), míg , ha az adott pozíció generál új átvivőt (azaz és is 1, ekkor biztosan lesz carry). Egy speciális előretekintő logika ezekből a és értékekből több bitre előre kiszámolja, mely pozícióknál lesz carry = 1. Például egy 4-bites carry lookahead egység képes megadni kimenetet ( bemenő carry alapján) egyetlen logikai szinttel és jeleken keresztül, ahelyett, hogy megvárná a ripple módon terjedést. Így a teljes összeadás ideje jelentősen csökken. A LACA felépítése bonyolultabb (több kaput igényel), de a késleltetés ~O(log N) lesz. Nagyobb bitméretekhez hierarchikusan több szintű carry lookahead is alkalmazható (pl. 16 bites blokkok carry-jét is előre számoljuk, stb.). Megjegyzés: A LACA (carry look-ahead adder) elnevezést a magyar szakirodalom néha CLA-ként (Carry Lookahead Adder) is rövidíti; a lényeg a hordozók előre számítása.
  • Teljes kivonó (Full Subtractor, FS): A bináris kivonás elvégezhető egy összeadóval is, ha a kivonandó számot kettes komplemens formában hozzáadjuk a másikhoz (és az ALU beépítetten képes inverterezni a bemenetet + kezdeti carry-t 1-re állítani). Direkt logikai úton is megvalósítható azonban félkivonó és teljes kivonó áramkörökkel. A félkivonó két egybites szám () különbségét adja és egy kölcsönző (borrow) kimenetet állít elő. A teljes kivonó három bemenettel dolgozik: , és az (az alacsonyabb helyiértékről jövő “kölcsön” bit), kimenete pedig a különbség bit és a kimenő kölcsön . Implementálható két félkivonóval hasonlóan, mint az összeadónál. A működés: (kivonásnál XOR-szerűen adódik a különbség bit, figyelembe véve a bemenő kölcsönt is), a pedig akkor lesz 1, ha vagy – vagyis ha kisebb mint vagy a bemenő kölcsönnel csökkentett kisebb, stb. A teljes kivonókat sorba fűzve (LSB-től indulva) kapunk ripple carry elven működő kivonó áramkört. Gyakorlatban azonban a kivonást általában nem külön áramkör végzi, hanem az ALU egy összeadója és invertáló logikája kombinálásával valósul meg (mivel képlettel történik). A dedicated FS ismerete inkább elméleti jelentőségű.

Szorzó és osztó áramkörök: hagyományos, fordított sorrendű, iteratív

  • Bináris szorzó algoritmusok (alapok): Két bináris szám szorzása logikailag hasonló a decimális kézi szorzáshoz: a szorzó minden egyes 1 bitje a szorzandó egy megfelelően eltolt példányát adja hozzá a rész-eredményhez. Hagyományos (sorozatos) szorzóáramkör: A legegyszerűbb megoldás egy iteratív shift-add algoritmus, amely LSB-től MSB felé halad: vizsgálja a szorzó legalacsonyabb bitjét, s ha az 1, hozzáadja a szorzandót a futó összeghez, majd a szorzandót balra shifteli, a szorzót jobbra shifteli, és lép a következő bitre. Ezt N-szer ismételve (N bites szorzó esetén) előáll a végeredmény. Ezt hardverben egy regiszterekkel, összeadóval és vezérlővel rendelkező áramkör végzi, mely minden órajelre 1 bitet dolgoz fel – ez egy iteratív szorzó, előnye hogy kevés hardvert használ (egy ALU is elég), hátránya hogy N lépésig tart a művelet.
  • Fordított sorrendű szorzó: Az iteratív algoritmus optimalizálható úgy, hogy MSB-től LSB felé haladunk, így ha a magasabb helyiértékű bitszakaszok nullák, az algoritmus hamarabb befejeződhet (nem kell végigfutni az összes biten). A fordított sorrendű szorzó figyeli a bemeneteket, és ha pl. a szorzóban hosszabb 0 sorozat van elején, átugorhat bizonyos lépéseket (adatfüggő gyorsítás). Ilyen elven működik a Booth-algoritmus is: a szorzó bitjeit kétbit csoportokban vizsgálja (pl. előző bitet is figyelembe véve), és egyszerre több 1-et kezel – csökkenti az összeadások számát negatív és pozitív részműveletek kombinálásával. A Booth-algoritmus különösen akkor hatékony, ha a szorzóban (vagy szorzandóban) sok a folytonos 1 vagy 0 bit. Ezzel lényegében fordított sorrendben is haladhat és az iterációk száma csökken. Összefoglalva: a fordított sorrendű, adatvezérelt szorzók a bemenet függvényében kevesebb lépést igényelnek, míg a hagyományos fix N lépést.
  • Párhuzamos (kombinatorikus) szorzók: A nagy teljesítmény érdekében lehetséges a szorzást teljesen kombinációs logikával megvalósítani (például részleges szorzatok mátrixa és azok összegző hálózata, pl. Wallace-tree). Ilyenkor N×M bites szorzó esetén akár kapuból álló hálózat is kialakulhat – nagyobb bitméretnél ez drága. A párhuzamos szorzók azonban egy órajel alatt eredményt adnak. Gyakorlati kompromisszum a pipeline-os szorzó: több órajel alatt készül el, de közben az adatfolyam több szorzást párhuzamosan, futószalagon kezel.
  • Osztó algoritmusok: A bináris osztást lehet közvetlen logikával (hasonlóan a hosszú osztás algoritmusához) vagy iteratív megoldással végezni. Hagyományos osztó (közvetlen áramkör): a restoring division algoritmust követi, mely N lépésben bitenként építi fel a hányadost. Minden lépésben összehasonlítja az aktuális maradékot a nevezővel, kivonja ha lehet, és a hányados bitjét ennek megfelelően állítja. A nem-restoring változat optimalizál, hogy ne kelljen minden lépésben visszaadni a maradékot (ha túlment a kivonás). A közvetlen osztóáramkörök bonyolultabb összehasonlító-kivonó logikát tartalmaznak és ritkábbak a gyakorlatban.
  • Iteratív osztó: Hasonlóan a szorzóhoz, egy regiszterekből és ALU-ból álló áramkör minden lépésben egy bitet képez a hányadosból. Az eljárás: balra shifteli a maradékot és a következő osztandó bitet “belehozza”, majd kivonja belőle az osztót; ha sikeres (nem lett negatív a maradék), akkor a hányados bit = 1, ha nem, vissza kell állítani a maradékot és a hányados bit = 0. Ezt N-szer ismételve kapjuk az N bites hányadost. Ez az iteratív (sorozatos) osztó fix N lépésben készül el, hardverigénye alacsony, de lassú.
  • Gyors osztási módszerek: Léteznek speciális algoritmusok a gyorsításra. Az egyik a Newton–Raphson módszer alkalmazása osztásra: közelítő reciprok érték iteratív finomítása lebegőpontos műveletekkel, mellyel néhány iteráció alatt nagyon pontos eredmény érhető el (pl. matematikai coprocesszorok használják). Egy másik a Goldschmidt algoritmus, ami párhuzamosítja a reciprokkal való szorzást. Ezek jellemzően lebegőpontos számításnál jönnek szóba. Digitális áramkör szinten az osztás gyorsítását jelentheti a maradék előre becslése több bitre (hasonlóan a carry lookahead elvhez a kivonásoknál), de leginkább a magasabb szinteken (pl. algoritmus, pipeline) optimalizálnak.

Digitális építőelemek: regiszterek, multiplexerek, dekódolók (és kódolók)

  • Regiszterek: A regiszter egy párhuzamosan kapcsolt flip-flop csoport, amely egy többszörös bitből álló bináris érték tárolására szolgál. Egy bites regiszter darab D-típusú flip-flopból épül fel, melyek közös órajellel vezéreltek. A regiszterben egy gépi szó (vagy cím, adat, utasítás) tárolható átmenetileg. A legtöbb CPU tartalmaz belső általános célú regisztereket (pl. akkumulátor, indexregiszterek), melyekben az ALU műveletek operandusai és eredményei tárolódnak. A vezérlőjel (írás/engedély) határozza meg, hogy az órajel élére a bemeneti adat betöltődjön-e a regiszterbe. Különleges regiszterek: számlálók (amelyek bizonyos logikával minden órajelre inkrementálnak/dekrementálnak), shift-regiszterek (melyekben a bitek egy pozícióval eltolódnak jobbra-balra a következő flip-flopba, tipikusan soros adatbevitelhez), stb.
  • Multiplexer (MUX): A multiplexer egy kapcsoló áramkör, amely több bemenet közül egyet köt a kimenetre a választójelek alapján. Egy bemenetű multiplexernek bitnyi vezérlő bemenete van, amely binárisan kijelöli, melyik adatbemenet jelenjen meg a kimeneten. Például egy 4:1 MUX-nál 4 adatbemenet és 2 vezérlőbit van; ha a vezérlő kód 10₂ (2 decimális), akkor a 2-es számú bemenet értéke kerül a kimenetre. A MUX lényegében választási lehetőséget ad a jelek között, fontos építőelem buszrendszerekben és ALU-knál (pl. választható, hogy az ALU egyik bemenetére a regiszterfájl melyik regisztere kerüljön). A multiplexer belül általában logikai ÉS–VAGY hálózatból épül fel (minden bemenethez egy ÉS kapu, ami a vezérlőbitek kombinációjára figyel, s ezek OR-ral összegződnek a kimenetre).
  • Demultiplexer (DEMUX): A demultiplexer az ellenkezője a MUX-nak: egy bemenetet kapcsol több lehetséges kimenet közül arra, amelyet a vezérlő jelek kijelölnek. Például egy 1-4 demultiplexernél a bemenő jel a vezérlőbitsorozat által meghatározott egyik kimeneten jelenik meg, a többi kimenet 0 lesz. A DEMUX az adatirány szétszórását valósítja meg – gyakran használják címdekódolásnál (pl. memóriacsip kiválasztásánál a cím felső bitjei alapján).
  • Dekódoló: A dekóder egy speciális demultiplexer, amely n bemeneti biten kap egy bináris számot, és kimenet közül pontosan egyet állít aktív (1) állapotba – azt, amelyik sorszámát a bemeneti bináris szám adja. Például egy 3-8 dekóder 3 bemenettel és 8 kimenettel rendelkezik: ha a bemenet pl. 101₂ (5 decimális), akkor a 5-ös számú kimenet = 1, az összes többi = 0. A dekódolók fontosak a címezésben: a CPU címvonalain megjelenő bináris címet dekódolja mondjuk a memórialap vagy I/O eszköz kiválasztására. A dekóder belső felépítése tipikusan AND kapuk hálózata, ahol minden lehetséges bemenet-kombinációhoz tartozik egy AND kapu (megkapja a bemeneti biteket valódi vagy negált formában, hogy pont arra a kombinációra legyen 1, és az lesz az adott kimenet).
  • Kódoló: Az encoder a dekóder inverz funkcióját látja el: bemenet közül (amelyek közül egy aktív 1, a többi 0) generál egy n bites kimenetet a „1” pozíció bináris indexével. Például egy 8-3 kódoló 8 bemenettel bír; ha mondjuk a 5. bemenet aktív (1), akkor a kimeneten 101₂ jelenik meg. A kódoló azt „kódolja”, melyik bemenet volt aktív. Használatos pl. megszakításkezelésben, ahol több eszköz kérhet megszakítást: az encoder a prioritás alapján kiválasztott eszköz azonosítóját adja át a CPU-nak binárisan. (Megjegyzés: Ha egyszerre több bemenet 1, azt prioritasos kódolóval lehet kezelni.)

Utasításkódolás és címzési módok

  • Utasításkódolás: A gépi szintű utasítások binárisan kódolt formában tárolódnak a memóriában. Egy utasítás általában tartalmaz egy műveleti kódot (opcode), ami jelzi a végrehajtandó műveletet, és operandus mezőket, melyek lehetnek regiszterazonosítók, memória címrészek vagy közvetlen (immediate) értékek. Az utasításkészlet architektúra (ISA) meghatározza az utasításformátumokat. Vannak fix hosszúságú utasításformátumú gépek (pl. sok RISC CPU minden utasítása 32 bites), és változó hosszúságú formátumúak (pl. CISC processzorok utasításai 1-15 byte hosszúak is lehetnek). A változó hossz bonyolítja a dekódolást, mert először meg kell állapítani az utasítás határát és hosszát, mielőtt értelmezné a jelentését. Az utasítások kódolása gyakran kompromisszum a bit-takarékosság (kisebb programméret) és a dekódolhatóság (egyszerű, gyors dekódolás) között.
  • Nulla-, egy-, két- vagy háromcímű utasítások: Az ISA-k eltérnek abban, hány címet/operandus adható meg egy utasításban. 0-című (stack) architektúránál nincsenek explicit operandusmezők – az ALU mindig a verem tetejéről veszi le a szükséges operandusokat, majd az eredményt visszateszi a veremre. Pl. egy ADD utasítás egyszerűen a veremből két számot vesz le és összadja. 1-című architektúránál tipikusan egy akkumulátor regiszter az egyik implicit operandus, így az utasítás csak a másik operandus címét tartalmazza. Pl. ADD X jelentheti: ACC = ACC + (mem). 2-című gépeknél egy utasítás két operandus címet tartalmaz (és sokszor az eredmény is az egyik helyére kerül, pl. ADD R1, X = R1 = R1 + (mem)). 3-című gépeknél mindhárom szereplő külön megadható (két forrás és egy cél), pl. ADD R1, R2, R3 = R1 = R2 + R3. A többcímű utasítások rugalmasabbak, de hosszabbak is lehetnek. A RISC processzorok gyakran 3-címűek (minden művelet explicit célregisztert ad meg, így elkerülhető a fölösleges adatmozgatás), míg régebbi CISC gépek 2-címűek voltak (az egyik operandus és a cél ugyanaz).
  • Címzési módok: Az operandusok címének értelmezését a címzési mód határozza meg. Az utasításkódban külön bitek vagy az opcode részlete jelzi, mely címzési mód érvényes az adott operandusra. Főbb címzési módok:
    • Közvetlen címzés (direct): Az operandus címe (memóriacíme) közvetlenül szerepel az utasításban. Például egy utasítás tartalmazza az X memóriahely címét, és a művelet azt az X címen lévő értéket használja. Ez egyszerű, de a cím mérete korlátozhatja az elérhető tartományt (ha nem fér bele az utasítás fix bitmezőjébe). Gyakorlatilag egy memóriacím-konstans van az utasításban.
    • Közvetett címzés (indirect): Az utasításban megadott cím valójában mutató egy másik címre. Az utasítás először kiolvassa az ott tárolt címet, majd arra hivatkozva éri el a tényleges operándust. Pl. ha egy utasítás LOAD (A) formájú (indirekt címmel), akkor a CPU előbb megnézi mem értékét, ami mondjuk B, ez lesz a valódi operandus címe, és végül mem-ből tölti az adatot. A közvetett mód rugalmas (pl. mutatók implementálása), de egy plusz memóriahozzáférést igényel.
    • Regiszter direkt: Az operandus a CPU egy regiszterében található, és az utasítás a regiszter kódját tartalmazza. Például ADD R1, R2 közvetlenül a R1 és R2 regiszterek tartalmát használja. Ez nagyon gyors (nem kell memóriahozzáférés az operandushoz), a címmező rövid (mert kevés regiszter van, néhány bit elég kódolni), viszont a regiszterek száma korlátozott.
    • Regiszter indirekt: Az utasítás egy regisztert jelöl meg, amely tartalmazza a memóriacímét a tényleges operandusnak. Tehát pl. MOV R1, (R2) azt jelenti: az R2 regiszter értékét címként használva töltsük be a mem tartalmát R1-be. Ezzel lehetőség nyílik hatékony tömbkezelésre, iterációra, hiszen R2 változtatásával mozgathatjuk a memóriahivatkozást.
    • Immediate (közvetlen operandus): Az operandus értéke közvetlenül be van ágyazva az utasításba, nem memóriából vagy regiszterből jön. Például ADD #5, R1 (ahol #5 jelöli a közvetlen 5-ös számot) hozzáad 5-öt R1-hez. Az immediate érték tipikusan az utasásszót követő bitekből áll. Előnye, hogy nincs memóriahozzáférés, gyors. Hátránya a korlátozott méret (az utasításnak tartalmaznia kell).
    • PC-relatív címzés: Irányított elágazásoknál gyakori. Az utasításban megadott érték nem abszolút cím, hanem egy elftolás (offset), amit a jelenlegi programszámláló (PC) értékéhez adva kapjuk meg a valódi címet. Pl. JMP +4 jelentheti, hogy 4-gyel előre ugrik az utasításfolyamban. Így az ugyanoda mutató elágazó utasítások pozíciófüggetlenül is működnek (ha kódot betöltik máshova, a relatív távolság ugyanaz marad). Általában kéttárolós kód generálásnál hasznos.
    • Indexelt és bázis (regiszter relatív) címzés: Ezeknél az utasításban két komponens adja a címet: egy bázis regiszter tartalmaz egy referencia címet, és az utasításban lévő offsetet hozzáadva kapjuk a tényleges memóriacímet. Ha a bázis fixen a PC, akkor ez PC-relatív (ld. előbb). Ha a bázis egy általános regiszter (pl. egy tömb kezdőcíme), az offset pedig az index (elem sorszáma * elemMéret), akkor indexelt címzésről beszélünk. Például LOAD R1, 20(R2) – töltsd be R1-be az adatot abból a memóriacímről, amit úgy kapunk, hogy R2 tartalmához hozzáadjuk 20-at. Itt R2 a bázis (báziscímzés), a 20 pedig az offset (displacement). Az indexelt címzést gyakran külön is említik, amikor egy dedikált indexregiszter értékét adják hozzá egy báziscímhez. A lényege, hogy hatékonyan lehet tömb elemeket elérni vagy struktúrákon belüli mezőket címzni.
    • Verem címzés: Implicit mód, 0-című utasításoknál már tárgyaltuk – pl. az PUSH X utasítás a verembe teszi X értékét, a POP X kiveszi. Az ALU műveletek (ADD, SUB stb.) pedig mindig a verem tetején lévő érték(ek)kel dolgoznak.
  • Példa utasításkódolásra: Vegyünk egy egyszerű RISC utasítást, pl. MIPS: ADDI $t0, $t1, 5. Ez egy 32 bites szóban kódolódik: [ opcode(6b) | rs(t0, 5b) | immediate (16b) ]. Itt az opcode jelzi az ADD immediate műveletet, rs a forrás regiszter (t1), rt a célregiszter (), az immediate mező pedig a 5 decimális érték (16 bites kettes komplemensben). A CPU dekódoláskor felismeri az opcode alapján a címzési módot is (hogy van immediate operandus), majd végrehajtja a műveletet.
  • Register Transfer Level (RTL) leírás: Az utasítások működését gyakran RTL formulákkal írják le, pl. ADD R1, R2 ⇒ R1 ← R1 + R2. A vezérlőegység mikroműveletekre bontva valósítja meg (pl. fetch, decode, operandus olvasás, ALU művelet, eredmény ír back).

Vezérlőegységek: huzalozott, mikrokódos, programozható logikák (PLD)

  • Huzalozott vezérlőegység (hardwired control): Ebben a megközelítésben a CPU vezérlőlogikája fixen, kapuk és szekvenciális áramkörök által van kialakítva. A vezérlő egység egy állapotgép (automata), amely az aktuális utasítás és a CPU állapot bitek (flag-ek) alapján generálja az egyes vezérlőjeleit a processzor többi részének (milyen műveletet végezzen az ALU, melyik regiszterből olvasson, írjon, memória-hozzáférés stb.). Huzalozott megvalósításnál gyakran Mealy vagy Moore modell szerinti szekvenciális hálózatot terveznek: a vezérlőállapot jelöli az utasítás végrehajtási ciklusának egy fázisát (pl. fetch, decode, execute, memory access, write-back), az állapot átmeneteket szinkron állapítja meg a kapuk kombinációja az utasítás kódjától függően. A huzalozott vezérlés előnye a gyorsaság (nincs extra memória a mikroprogramhoz, kevesebb lépcső), valamint a potenciálisan kisebb chipterület bizonyos egyszerű RISC esetben. Hátránya a rugalmatlanság: nehéz változtatni vagy bővíteni (minden módosítás új áramköri tervet igényel), bonyolult utasításkészletnél a logika nagyon összetett lehet.
  • Mikrokódos vezérlőegység (microprogrammed control): Itt a vezérlő logika egy kisebb beágyazott „program” formájában valósul meg, amelyet egy gyors, speciális vezérlőmemória (mikroprogram-tár) tárol. Az egyes gépi utasítások végrehajtását egy mikroprogram (mikroutasítások sorozata) valósítja meg. Minden mikroutasításban kódolva vannak a vezérlőjelek (pl. buszvezérlő jelzők, ALU műveleti kód stb.), és a következő mikrocímre vonatkozó információ (feltétel a következő lépéshez). Amikor a CPU egy utasítást dekódol, a dekóder belépési pontot ad a mikroprogramnak, onnan indulva a mikrokód lépésről lépésre végrehajtja az utasítást. Ez hasonló egy belső interpreterhez: a bonyolult CISC utasítások sok apró lépésre bonthatók (pl. memória olvasás, ALU művelet több fázisban, stb.), melyeket a mikroprogram sorra vesz. Előnye: a vezérlő logika rugalmas – új utasítás bevezethető a mikroprogram módosításával (hardver változtatás nélkül, sőt néha futás közben is lehet firmware frissítéssel, pl. mikrokód patch). Egyszerűsíti a tervezést, mert egy bonyolult műveletet könnyebb mikrokódolni, mint tisztán kapukkal megoldani. Hátrány: általában lassabb, mert a mikroprogram lépések extra ciklusokat adnak (egy CISC utasítás több belső ciklust igényel). Modern processzoroknál kompromisszum: a gyakori utasítások (vagy RISC mag) huzalozottan mennek, ritkább komplex utasítások mikrokódra bízhatók.
  • Vezérlő memóriák és mikrokódszervezés: A mikroprogram lehet horizontális (nagyon széles mikroutasítás szó, melyben minden vezérlőjel külön bit helyet kap – közvetlen vezérlés) vagy vertikális (keskenyebb mikroutasítás, kódolt mezőkkel, amit egy kis dekóder bont szét vezérlőjelekké). A horizontális gyorsabb (párhuzamos jelek, nincs dekódolás), de nagy memória kell hozzá; a vertikális takarékosabb, de lassabb. Sok architektúra kompromisszumos megoldást használ. A mikrocímtár általában tartalmaz feltételes ugrási logikát (pl. ha egy ALU flag bizonyos értékű, ugorjon a mikrokód egy másik címére, különben sorban megy tovább), így valósulnak meg ciklusok, feltételek a mikrokódban. A mikroutasításokat tipikusan egy ROM vagy PLA (Programmable Logic Array) tárolja a CPU-n belül.
  • Programozható logikai eszközök (PLD) alkalmazása: A vezérlőegység (akár huzalozott, akár mikrokódos) implementálható programozható logikával is. Régen gyakori volt a PLA használata az utasításdekódoló és vezérlő logika implementálására: a PLA egy programozott AND-OR mátrix, ami logikai függvényeket valósít meg. A CPU utasítás kód bitjei mentek a PLA bemenetére, ami generálta a szükséges vezérlőjeleket és/vagy mikrocímeket. Manapság a CPU tervezése során belsőleg testreszabható logikai cellák (szilíciumon dedikált áramkörök) valósítják meg a vezérlést, de elviekben használhatók CPLD vagy FPGA eszközök is egy CPU építésére. Oktatási és prototípus célból szoktak is FPGA-n soft-core processzorokat megvalósítani. A PLD-k csoportjába tartozik a PROM alapú logika (tulajdonképpen mikroprogram-tár is lehet PROM), a PAL (Programmable Array Logic) és GAL, valamint az EPROM/EEPROM/Flash alapú kombinatorikus logikák. Az FPGA-k (mezőn programozható kaputömbök) pedig több ezer logikai kaput és tárolót integráló eszközök, melyekben a vezérlőegység komplett áramköre konfigurálható. A programozhatóság a vezérlésben azt adja, hogy a CPU viselkedése utólag módosítható a logika újraprogramozásával – ez különösen beágyazott rendszereknél jöhet jól, vagy prototípus fejlesztésnél. A modern CPU-k nem klasszikus értelemben programozhatók (fix maszkosak), de pl. a mikrokód frissíthető egy flash memóriában tárolva (javításokat befoltozni).

I/O rendszerek: arbitráció, szinkron és aszinkron kommunikáció

  • I/O alrendszer szerepe: A számítógép Input/Output (I/O) rendszere köti össze a CPU-t és memóriát a perifériákkal (billentyűzet, monitor, háttértárak, hálózat stb.). Mivel több eszköz csatlakozhat, és a CPU-val párhuzamosan, illetve egymástól függetlenül működhetnek, szükség van mechanizmusokra a kommunikáció ütemezésére és ütközések elkerülésére.
  • Busz arbitráció (hozzáférés vezérlés): Ha egy rendszeren több buszmester is lehet (pl. CPU és DMA vezérlő vagy több processzor, illetve több eszköz egy közös buszon), akkor meg kell oldani, hogy egyszerre csak egy mester használja a buszt. Az arbitráció ennek a döntése. Többféle módszer van:
    • Párhuzamos arbitráció: Minden eszköznek van egy külön kérő vonala a központi arbiter felé, és az arbiter egyszerre látja mindegyik igényt. A döntést egy prioritási áramkör hozza (pl. fix prioritás vagy forgó-prioritás). Az arbiter párhuzamosan jelzi vissza a grant-et annak az egynek, aki nyert. Ez gyors (egy ciklus alatt eldönthető), de sok vezeték kell (N eszköznél N kérés és N grant vezeték).
    • Soros arbitráció: Az eszközöket daisy-chain láncba kötjük: egy busz kérés vonalat felfűzünk rajtuk, és egy engedély (grant) jelet is. A CPU vagy buszvezérlő elindít egy grant jelet, ami sorban halad át az eszközökön; az első eszköz, amelyik kérte a buszt, “megragadja” a grant-et és nem adja tovább, így a lánc vége felé lévők nem kapják meg ebben a körben. Ez egyszerű és kevesebb vezeték (csak egy kérés és egy grant vonal), de a lánc elején lévő eszközök előnyben vannak (prioritási sorrend rögzítve a lánc sorrendjével).
    • Lekérdezéses arbitráció: A központi vezérlő (tipikusan a CPU) szoftveresen vagy hardveresen körbekérdezi az eszközöket, van-e igényük. Például egy regisztertérben minden eszköznek van egy státuszbitje, a CPU ciklikusan ellenőrzi ezeket (polling), és akit aktívnak talál, annak ad lehetőséget. Ez implementálható hardver buszcyklusokkal is (címkörbeküldés, eszköz válaszol-e). A polling egyszerű, de időigényes lehet és a CPU-t terheli; csak kisebb rendszereknél használatos közvetlenül arbitrációra.
  • Szinkron vs aszinkron kommunikáció:
    • Szinkron busz: A kommunikáció résztvevői egy közös órajel üteméhez igazodnak. A busz vezérlő jelei és az adatátvitel fix időzítési diagram szerint történnek (pl. egy órajel-ciklus alatt érvényes a cím, a következőben már az adat, stb.). A szinkron protokoll előnye, hogy egyszerűbb a logika (mindenki ugyanazt az órát használja, nincs szükség külön kézfogó jelekre az időzítéshez). Hátránya, hogy a busz sebességét a leglassabb eszközhöz kell igazítani, és a távolság korlátozott az órajel épsége miatt.
    • Aszinkron busz: Nincs közös órajel; a kommunikáció kézfogó (handshake) protokollal zajlik. A kezdeményező (master) kihelyezi a címet és vezérlőjelet, majd jelez egy Request (REQ) vonalon. A cél (slave) amikor elérhető és az adat készen áll, egy Acknowledge (ACK) jellel válaszol. Csak ekkor veszi át a master az adatot, majd a tranzakció lezárul. Az aszinkron protokoll rugalmas: minden eszköz a saját tempójában dolgozhat, a gyorsabb nem vár többet a szükségesnél, a lassabb kap annyi időt amennyit igényel. Nincs frekvencia korlát, nagy távolságra is működhet. Cserébe a vezérlő logika bonyolultabb (state machine kell a kézfogóhoz), és tipikusan kicsit lassabb throughput érhető el, mert a kézfogó jelek átfutási ideje plusz overhead.
  • Interrupt vs polling: (Bár a kérdésben nem szerepel kifejezetten, az I/O kommunikáció fontos eleme.) A CPU az I/O műveleteket két alapprotokollal indíthatja: programozott kérdezéssel (polling), vagy megszakítás vezérléssel (interrupt). Pollingnál a CPU periodikusan figyeli az eszközök állapotát (készen van-e az adat?), ami CPU időt pazarolhat. Megszakításnál a periféria aszinkron jelet küld a CPU felé, amikor figyelmet igényel, a CPU pedig félbeszakítva a futó programot kiszolgálja azt (interrupt service routine). A busz arbitrációnál is felmerül: több eszköz egyidejű interrupt-jánál dönteni kell, ki kapjon elsőbbséget (gyakran interrupt vezérlő chip kezeli prioritással vagy vektorral).
  • Összefoglalás: Az I/O rendszerek tervezésénél kulcs a párhuzamosság kezelése: a CPU és eszközök eltérő sebességét buffereléssel (pl. pufferregiszterek, FIFO-k), a buszmegosztást arbitrációval, az időzítés-összhangot pedig vagy egy mindenki által követett órajellel (szinkron), vagy rugalmas handshake protokollal (aszinkron) oldjuk meg.

IO buszok: PCI, PCI-Express, SCSI

  • PCI busz (Peripheral Component Interconnect): A PCI egy párhuzamos, szinkron lokális busz, amit a CPU és az alaplapi perifériák összekapcsolására terveztek (1990-es évek). 32 vagy 64 bites sín, közös osztott busz topológiával (minden eszköz ugyanarra a buszvonalra csatlakozik). A PCI árbiter dönti el, melyik eszköz használhatja a buszt (mert egyszerre csak egy mester adhat adatot). A PCI protokoll szeparálja a címszakaszt és adatszakaszt (multiszálas műveletek), támogat burst adatátvitelt (folytonos többszavas adatblokk átvitel). Az órajele tipikusan 33 MHz (vagy 66 MHz), 32 biten ez ~133 MB/s sávszélességet ad, ami megoszlik az eszközök között. A PCI egy memória- és IO-tér címzést is megkülönböztet (külön címtartományokat). Későbbi kiterjesztések: PCI-X (nagyobb órajel, 64 bites), de végül a PCI-Express váltotta fel.
  • PCI Express (PCIe): A PCIe a PCI utódja, de teljesen más alapelvekkel: ez egy soros, pont-pont kapcsolt kommunikációs hálózat (switch-ekkel), nem egy osztott párhuzamos busz. A PCIe link egy vagy több sávból (lane) áll: egy sáv két pár differenciális vonal (egyik irányba Tx, másikba Rx), melyek nagy frekvencián sorosan továbbítják az adatokat. Egy lane PCIe 1.0-ban ~250 MB/s irányonként, PCIe 2.0-ban ~500 MB/s, PCIe 3.0-ban ~1 GB/s, stb. A kártyák gyakran ×1, ×4, ×8, ×16 lane konfigurációk, pl. egy ×16 PCIe 3.0 slot elméletileg ~16 GB/s összesített átvitelre képes (duplex, kétirányú össz-sávszélesség). A PCIe protokoll csomagkapcsolt: az adatokat csomagokba formázza, és a topológiában switch-ek routolják a megfelelő eszközhöz (hasonlóan mint egy hálózat). Előnyei: skálázható sávszélesség (több lane, magasabb generációs órajel), teljes duplex kommunikáció, nincsenek osztott vonal miatti torlódások. A PCIe visszafele kompatibilis szoftveresen a PCI-val (hasonló konfigurációs tér, ugyanazt a driver modellt támogatja), de fizikailag és elektromosan teljesen más. A generációk kb. duplázzák a sebességet: PCIe 4.0 ×16 ~32 GB/s, PCIe 5.0 ×16 ~64 GB/s, PCIe 6.0 ×16 ~128 GB/s sávszélességet tud ideálisan. A PCIe támogatja a hot-plug-et, és speciális protokollokat pl. Memory Mapped I/O, interrupt kezelést Message Signaled Interrupt formában, stb.
  • SCSI busz (Small Computer System Interface): A SCSI egy parallel perifériabusz szabvány, főként háttértárak (merevlemezek, szalagok, optikai meghajtók) csatlakoztatására. A klasszikus SCSI busz 8 vagy 16 adatvezetékkel rendelkezik (Narrow SCSI = 8 bit, Wide SCSI = 16 bit), és támogathatott akár 8 vagy 16 eszközt egy láncban (minden eszköznek SCSI azonosítója van, ID0-7 vagy 0-15) – beleértve a host adaptert is, ami maga is a busz egy résztvevője. A SCSI busz daisy-chain formában van lezárva mindkét végén (vonalterminálás szükséges). Az eszközök a buszt megosztják: van arbitráció a SCSI-n belül is – ha több eszköz akar kommunikálni, a SCSI protokoll dönti el (általában ID alapján prioritás, magasabb ID nyer, vagy fairness). A SCSI intelligensebb volt, mint a korabeli ATA: támogat parancssorba állítást, aszinkron és szinkron módot is (két fél megegyezhet órajel alapú szinkron átvitelben a buszon a gyorsításért), és akár egymással párhuzamosan is futhat több parancs (disconnect/reconnect protokoll: egy lemez miután elindít egy hosszú műveletet, lekapcsolódik a buszról, hogy más eszköz használhassa addig). A SCSI sebessége az évek során nőtt: SCSI-1 (5 MB/s), SCSI-2 Fast (10 MB/s), Ultra SCSI (20 MB/s), Ultra2 (40 MB/s), Ultra3/Ultra160 (160 MB/s), Ultra320 (320 MB/s) – ezek a busz teljes sávszélességei. A parallel SCSI-t később felváltotta a Serial Attached SCSI (SAS), ami soros pont-pont link (tulajdonképpen rokon a SATA-val, de fejlettebb több cél, multipath stb.). A SCSI ma is létezik SAS formájában szerver környezetben, de a hagyományos párhuzamos SCSI busz már ritka. A történelmi jelentősége, hogy multimester busz volt (pl. két számítógép is osztozhatott egy SCSI buszon), és a protokollja számos fogalmat bevezetett, amik máshol is megjelentek (parancs fázisok, LUN-kezelés, buszarbitráció).
  • Egyéb I/O buszok: A kérdés csak a PCI, PCIe, SCSI-t említi, de említésképp: a PC-k világában volt ISA (régi XT/AT busz, lassú), AGP (grafikus gyorsító port, a PCI egy speciális, point-to-point verziója VGA-hoz), az ipari/beágyazott területen sok busz (VME, PCI-X, CompactPCI, stb.), a külső I/O-hoz USB, Thunderbolt, stb. A lényeg, hogy az I/O buszok mindig egyensúlyoznak a sávszélesség, távolság, költség, és kompatibilitás szempontjaival. A PCIe jelenleg a tipikus belső nagysebességű összeköttetés PC-ben (grafika, NVMe SSD, hálózati kártyák), míg a SCSI (SAS) a szerver tárolók világában, a PCI pedig már legacy (visszafelé kompatibilis támogatásként esetleg jelen van lásd PCIe-to-PCI híd formájában).

RISC és CISC architektúrák különbségei

  • CISC (Complex Instruction Set Computer): A hagyományos értelemben vett CISC processzorok nagyon gazdag és összetett utasításkészlettel rendelkeznek. Sokféle, akár több száz utasítástípust, és számos címzési módot támogatnak. Egyetlen utasítással sok lépéses műveletet lehet elvégezni (pl. memória memóriába másolás, string műveletek, komplex aritmetikai műveletek több operandussal). Az utasítások hossza változó, lehet rövid (1-2 byte) vagy nagyon hosszú is, a konkrét operandusoktól függően. Emiatt a dekódoló logika bonyolult: előbb meg kell állapítania, hány byte-os az utasítás, mely mezők mit jelentenek, csak azután tudja vezérelni a végrehajtást. A CISC filozófia abból indult ki, hogy a magas szintű nyelvek utasításait közvetlenül, kevés gépi utasítással lehessen megvalósítani – csökkentve a programozó (vagy fordító) terhét és a program méretét (pl. a korai CISC gépekben kevés memória volt, fontos volt a kompakt kód). Jellemzően CISC gépeknél megengedték, hogy az ALU utasítások közvetlenül a memóriát is használják operandusként (pl. ADD mem, reg összead egy memóriahelyet és egy regisztert). Példák: x86 architektúra, VAX, 68000 sorozat – mind gazdag utasításkészletű. Előnyök: rövidebb programkód (kisebb memóriaigény), egyes bonyolult műveletek gyorsabbak lehetnek, ha egy utasítással mennek (pl. blokkmozgatás). Hátrányok: a komplex utasítások ritkán használtak (átlagos futásidőben az utasítások 20%-a felel az idő 80%-áért – sok CISC utasítás alig használódik), mégis helyet foglalnak, és a dekódoló meg a vezérlőegység miatt a hardver nagy és lassabb lehet. A változó hosszúság és memóriaműveletek nehezítik a pipeliningot és a párhuzamos végrehajtást.
  • RISC (Reduced Instruction Set Computer): A RISC architektúra ezzel szemben egy letisztult, minimális utasításkészletet alkalmaz, melynek utasításai általában egyszerűek, fix hosszúságúak és közel azonos végrehajtási idejűek. Fő jellemzői:
    • Load/Store architektúra: Az ALU (aritmetikai-logikai) utasítások csak regiszterek között működnek, memóriát közvetlenül nem manipulálnak. Az adatok betöltése és tárolása a memóriából külön utasításokkal (LOAD, STORE) történik. Ezzel elérik, hogy a legtöbb utasítás (az ALU-s) nagyon egyszerű és gyors legyen, a memóriaműveletek pedig rendezettek (és a pipeline-ban jól kezelhetők, pl. eltolhatók).
    • Sok (általános célú) regiszter: Mivel a memóriahozzáférés korlátozott a load/store-ra, a RISC CPU sok regisztert biztosít, hogy az aktív adatok ott elférjenek. Gyakori a 32 vagy több darab 32 bites regiszter. Ezzel csökkentik a memória műveletek számát (ami lassú lenne), és a fordító optimalizálhatja, hogy a változókat regiszterben tartsa. (Némely RISC, pl. SPARC implementál regiszter ablakokat, hogy függvényhívásoknál se kelljen menteni/állítgatni túl sokat – a hívások között csúszóablak-szerűen használ új regiszterhalmazt).
    • Egyszerű utasításformátum és dekódolás: Általában 1 szó = 4 byte = 32 bites minden utasítás. Az utasítás mezői fix pozíción vannak (pl. 6 bit opcode, 5-5 bit regiszter operandusok, stb.), így a dekódolás nagyon gyors (gyakran egy órajel alatt megy). A kevesebb utasítástípus miatt a vezérlő logika egyszerűbben huzalozható.
    • Pipelining kihasználása: A RISC CPU-k tervezésénél nagy hangsúlyt kap a pipeline technika – az utasítás végrehajtását fázisokra bontják (pl. Fetch, Decode, Execute, Memory, Writeback), és ezek olyan párhuzamos futószalagot alkotnak, hogy egyszerre több utasítás különböző fázisai futnak a CPU külön részegységein. Ennek előfeltétele, hogy az utasítások egyszerűek és uniformizáltak legyenek (nehogy egy bonyolult utasítás megakassza a pipeline-t). A RISC filozófia utasításai tipikusan 1 ciklus alatt hajthatók végre (a memóriaelérést nem számítva, ami külön utasítás), így jól pipeline-ozhatók. Több végrehajtó egység (pl. integer ALU, FP egység, load/store egység) párhuzamosan is dolgozhat külön utasításokon – ez a szuperskalár kiterjesztés, ami CISC-nél is alkalmazható, de RISC-nél könnyebben.
    • Egyszerűség vs kódhossz: A RISC-nél egy komplex művelet megvalósításához több egyszerű utasítás kellhet, így a programkód hossza növekedhet. Azonban a RISC utasítások gyakran még így is összességében gyorsabb futást eredményeznek a magasabb órajel és párhuzamosság miatt. A tipikus RISC utasítások: egyszerű aritmetika/logika, összehasonlítás/ugrás, load/store, és nagyon kevés speciális (pl. trap hívás OS-hez).
    • Kevesebb címzési mód: RISC processzorok kevés, jól használható címzési módot támogatnak (pl. regiszter indirekt offsettel, PC-relatív ugrás), ezzel is egyszerűsítve a dekódolást és vezérlést.
  • RISC vs CISC a gyakorlatban: A modern x86 processzorok belsőleg mikroarchitektúra szinten RISC-szerűek: a bonyolult CISC utasításokat a dekóder rövidebb mikro-utasításokká (uop) bontja, és egy RISC-szerű végrehajtómotor hajtja végre őket (több párhuzamos ALU-val, pipeline-okkal). Így próbálják kombinálni a CISC előny (kompatibilitás, kódtömörség) és a RISC előny (sebesség, pipeline) egy részét. Tisztán RISC példák: MIPS, ARM, SPARC, POWER – ezek sokáig egyszerűek voltak, bár az évek során bővültek (pl. DSP utasítások, SIMD, stb., ami növeli a komplexitást). A RISC és CISC közti különbség ma már inkább történelmi/koncepcionális, de a lényeg: RISC – kevesebb, egyszerűbb utasítás fix formátumban, CISC – több és komplexebb utasítás változó formátumban. Ennek következményei a belső felépítésre és teljesítményre vannak.
  • Tipikus különbségek összefoglalva:
    • Utasítások száma: RISC néhány száz alatt, CISC akár több ezer variáns.
    • Utasítások hossza: RISC fix (általában 4 byte), CISC változó (1-15 byte).
    • Címzési módok: RISC kevés (~3-5 fő mód), CISC nagyon sok (x86-ban pl. komplex bázis+index+offset variációk).
    • Mikrokód: RISC általában nem igényel mikroprogramot (huzalozott vezérlés), CISC tipikusan mikroprogramozott (különösen a ritka utasításoknál).
    • Regiszterek: RISC sok általános regiszter (pl. 32), CISC kevesebb (pl. x86-nál hagyományosan 8), bár újabb x86-64 már 16 regisztert ad.
    • Memória operandusok: RISC csak load/store, CISC ALU utasítás közvetlenül is mehet memóriára.
    • Teljesítmény: RISC egyszerűbb pipeline → magasabb órajel érhető el egy adott technológiával, és jobb pipeline kihasználtság, de több utasítás a feladatban; CISC kevesebb utasítás, de egyenként lassabb végrehajtás és nehezebb pipeline.
    • Példa: Egy string összehasonlítás CISC-en lehet egy CMPS utasítással megoldható, RISC-en egy hurkot kell írni load/compare/branch utasításokból. CISC-nél a mikrokód végzi a hurkot belül, RISC-nél a szoftver, de közben a pipeline pörög.

Magas szintű szintézis és FPGA-k szerepe

  • Magas szintű szintézis (HLS): A magas szintű szintézis olyan tervezési módszertan, amelynek során magasabb szintű nyelven (pl. C/C++, MATLAB, Python, vagy speciális HLS nyelv) írjuk le a kívánt funkciót, és egy eszköz automatikusan hardver leíró nyelvű (HDL, pl. Verilog vagy VHDL) implementációt generál belőle. Ez lehetővé teszi, hogy a hardvertervezés magasabb absztrakciós szinten, gyorsabban történjen, mivel a tervezőnek nem kell bit-szintű szinten manuálisan megírnia a logikát, hanem a fordító végzi el az ütemezést, erőforrás-hozzárendelést, stb. A HLS eszközök a forráskódot (pl. egy C függvényt) hardver architektúrára fordítják: ez magában foglalja a műveletek ütemezését órajeli ciklusokra (scheduling), a szükséges erőforrások (aritmetikai egységek, memória-portok) allokálását és összekapcsolását, pipeline-ok automatikus beillesztését, stb. A végeredmény egy RTL szintű modul lesz, ami funkcionálisan megfelel a magas szintű leírásnak. Például egy képfeldolgozó algoritmust HLS-sel pár soros C kódból lehet lefordítani egy pipeline-olt, párhuzamos hardver rendszerré. Előnyei: drasztikusan csökkentheti a fejlesztési időt, a magas szintű algoritmusváltoztatások könnyebben kipróbálhatók, a tervező a funkcióra koncentrálhat a helyett, hogy flip-flopokkal és vezérlő állapotgépekkel bíbelődik. Hátrányai: az így generált áramkör nem mindig olyan optimális, mint a kézzel tervezett (bár rengeteget fejlődött, a mai HLS eszközök már egészen hatékony kódot képesek előállítani tipikus feladatokra), és a tervezőnek ismernie kell a HLS eszköz korlátait (pl. mely kódszerkezetek fordulnak hatékony hardverre és melyek nem).
  • FPGA (Field-Programmable Gate Array): Az FPGA egy olyan integrált áramkör, amely hatalmas mennyiségű logikai kaput, programozható interkonnekt hálózatot és beágyazott erőforrásokat tartalmaz, és utólag (a gyártás után, a felhasználó által) programozható a kívánt funkció ellátására. Az FPGA felépítésének lényege: sok ezer konfigurálható logikai blokk (CLB), amelyek tartalmaznak programozható LUT-okat (look-up table, amiben tetszőleges kis logikai függvény valósítható meg), és flip-flopokat, valamint kapcsoló mátrixok a blokkok összekötésére, továbbá gyakran dedikált erőforrások: pl. blokkmemóriák (RAM blokkok adat tárolásra), DSP slice-ok (gyors szorzó-összegző áramkörök), és IO csatlakozók. A felhasználó egy hardware description language (HDL) segítségével írja le a kívánt digitális áramkört, amit a szintézis eszköz lefordít az FPGA alacsony szintű konfigurációjára (bitstream). Az FPGA előnye, hogy rugalmas: ugyanaz a chip újrakonfigurálható teljesen más funkcióra (akár futás közben is újrakonfigurálható részlegesen), nem kell új IC-t tervezni gyökeresen eltérő logikához. Ezért ideális prototípus készítésre – pl. egy új processzorarchitektúrát FPGA-n valósítanak meg és tesztelnek, mielőtt ASIC-ként gyártanák le. Használják továbbá alacsony-közepes példányszámú végtermékekben is, ahol nem gazdaságos saját chipet gyártani, illetve olyan alkalmazásokban, ahol idővel frissíteni kell a hardvert (pl. kommunikációs eszközök protokollját új verzióra). Az FPGA-k teljesítménye jellemzően elmarad a hasonló feladatra tervezett egyedi IC-től (lassabb órajel, nagyobb fogyasztás), de mégis óriási számítási teljesítmény érhető el velük bizonyos párhuzamos feladatokban, mert nagyon sok műveletet képesek egyidejűleg, testreszabott bit-szélességgel végezni (pl. kriptográfia, AI gyorsítók, digitális jelfeldolgozás).
  • FPGA-k szerepe a modern számítógép-architektúrákban:
    • Prototípus és fejlesztés: Ahogy említettük, egy új CPU vagy SoC architektúrát általában először FPGA-n próbálnak ki (szimulációnál nagyságrenddel gyorsabb a valós hardver prototípus). Az FPGA prototípuson a fejlesztők futtathatnak szoftvert, tesztelhetik a perifériákat stb., mielőtt véglegesítik a chip terveit.
    • Beágyazott rendszerek: Vannak Soft-core processzorok, amik FPGA logikából megvalósított, konfigurálható CPU-k (pl. Xilinx MicroBlaze – egy 32 bites RISC mag, ami az FPGA belső erőforrásaiból épül fel; vagy Altera Nios II). Ezekkel a mérnök egyedi processzort integrálhat a logikába, pont annyi erőforrást használva, amennyi kell, és testre szabhatja (pl. speciális utasításokat adhat hozzá az adott alkalmazáshoz). Sok FPGA tartalmaz hard-core beágyazott processzort is (pl. Xilinx Zynq család dupla ARM Cortex-A9-cel, Intel SoC FPGA-k ARM maggal), így ötvözi a programozható logikát és a hagyományos CPU-t.
    • Hardvergyorsítás: Adott számítási feladatokat (pl. gépi tanulás, kriptográfia, jelfeldolgozás) az FPGA logika párhuzamos architektúrával sokkal gyorsabban elvégezhet, mint egy általános CPU. Az utóbbi években pl. adatközpontokban FPGA-kat használnak bizonyos feladatok gyorsítására (például a Microsoft projekt Catapult az AI inferenciához). Az architekturális szempont itt az, hogy a von Neumann elvű processzor mellett specializált konfigurálható táregységek működnek, amik a feladatnak megfelelő architektúrát valósítanak meg.
    • Magas szintű szintézissel: a tervező számára leegyszerűsödik a specifikus hardver funkciók készítése – pl. egy videó kódoló algoritmust leír C-ben, a HLS lefordítja FPGA-ra, így nincs szükség chiptervező mérnökök hadára. Ez demokratizálja a hardvertervezést bizonyos mértékig.
  • Összefoglalva: Az FPGA-k és a HLS kombinációja egyre fontosabb: lehetővé teszi testreszabott architektúrák gyors létrehozását. Míg a klasszikus számítógép-architektúra fix hardverrel dolgozik, addig a programozható logika révén átjárható a határ szoftver és hardver között – bizonyos feladatokat szoftverből a „hardverre tolhatunk” (hardware offloading). Ez a gondolat az ún. re-konfigurálható számítástechnika alapja, ami sok kutatás tárgya.

Számítógép generációk és technológiai fejlődés

  • Első generáció (1940-es évek vége – 1950-es évek közepe): Elektroncsöves számítógépek. Ezek a gépek diszkrét elektroncsövekkel (vákuumcsövekkel) épültek, amelyek kapcsolóként működtek (logikai 0/1 váltására). Jellemzőik: hatalmas méret (szobányi gépek), nagyon nagy energiafogyasztás és hőtermelés, alacsony megbízhatóság (az elektroncsövek gyakran kiégtek), kezdetleges számítási sebesség a maihoz képest. Programozásuk gépi kódban vagy akár kötőpanel átdugással történt (mint az ENIAC esetében, ahol a programot fizikai csatlakozók átkötésével konfigurálták), később megjelent a tárolt program elv (Neumann-elvek). Példák: ENIAC (1946, USA) – 18000 elektroncső, 5 000 operáció/másodperc; EDVAC, EDSAC (első Neumann-elvű gépek), UNIVAC I (1951, első kereskedelmi számítógép). Az adatok és programok lyukkártyán vagy lyukszalagon kerültek bevitelre. Memória: higany késleltetővonalak vagy mágnesdob (mágneses henger), később ferritgyűrűs memória kezdemények. Az első generáció végén már assembler szintű programozás is megjelent az abszolút gépi kód helyett.
  • Második generáció (1950-es évek vége – 1960-as évek közepe): Tranzisztorok megjelenése. 1947-ben találták fel a tranzisztort, az 50-es évek végére a számítógépekben is felváltották az elektroncsöveket. A tranzisztor sokkal kisebb, megbízhatóbb, kevesebbet fogyaszt, nem melegszik úgy és gyorsabb kapcsolású, mint egy elektroncső. Ez radikális megbízhatóság- és méretjavulást hozott. A gépek még mindig diszkrét elemekből álltak (ellenállások, kondenzátorok, tranzisztorok vezetékekkel kötve), de jóval kisebbek lettek (szekrény nagyságúak), és kevesebbet fogyasztottak. Példák: IBM 7090 (1959, tranzisztoros), CDC 1604. A programozás terén megjelentek az első magas szintű nyelvek: FORTRAN (1957), COBOL (1959) – a fordítóprogramok lehetővé tették, hogy a gépeket szélesebb kör használja. A memóriában a ferritgyűrűs tároló vált standarddá (mikromásodperces elérési idők). Perifériák terén: lyukszalagról áttérés mágnesszalagra, az adatbevitel-kiadás még sokszor papíron (kártya, nyomtató) történt. A megbízhatóság és teljesítmény annyit javult, hogy üzleti, adminisztratív feladatokra is elkezdték használni (nem csak tudományos számításra).
  • Harmadik generáció (1960-as évek közepe – 1970-es évek közepe): Integrált áramkörök (IC-k) alkalmazása. Itt történt az áttörés, hogy sok tranzisztort egyetlen szilícium lapkára integráltak (SSI – Small-Scale Integration, majd MSI – Medium-Scale Integration chipek). Először csak kapuáramkörök (pár tranzisztor) voltak egy tokban, de így is hatalmas mértékben csökkent a gépek mérete és nőtt a sebesség (a jelterjedési késleltetés is csökkent, hiszen most már egy chipen belül vannak a tranzisztorok). E generációt az IBM System/360 (1964) szimbolizálja: ez volt egy család, amely lefedte a teljes piaci spektrumot, és binárisan kompatibilis volt felfelé; a gépek már operációs rendszert futtattak (OS/360), multiprogramozást, időosztásos rendszert valósítottak meg. Megjelent a párhuzamos feldolgozás csírája (pl. csővezetékes műveletvégzés, I/O processzorok a háttérben), a multiprocessing (több CPU egy gépben). A harmadik generáció hozta az első miniszámítógépeket is – kisebb, olcsóbb gépek, pl. DEC PDP-8, PDP-11 –, amik már laborok, kisebb intézmények számára is elérhetők voltak nem csillagászati áron. A fejlesztési technológia: továbbra is TTL integrált áramkörök hordozólemezeken, de a méret/ár csökkent. A magas szintű nyelvek elterjedtek (pl. BASIC, Pascal megjelent), az OS-ek fejlődtek (soros batch feldolgozás mellett interaktív time-sharing).
  • Negyedik generáció (1970-es évek közepe – napjainkig – de szűkebben 1970s-1980s): LSI/VLSI mikroprocesszorok és mikrocomputerek. 1971-ben az Intel megalkotta a 4004-et, az első mikroprocesszort (egy chipen egy teljes 4 bites CPU). Ezzel kezdetét vette a mikroprocesszorok kora. A LSI (Large-Scale Integration) azt jelentette, hogy több ezer tranzisztor, a VLSI (Very Large) pedig több százezer/millió feletti tranzisztorszám egy chipen. A 4. generációban a komplett CPU már egyetlen integrált áramkör (vagy néhány) lett, a memória is félvezető lapkákból állt (dram, sram chipek), így a számítógép mérete radikálisan lecsökkent: megjelentek a személyi számítógépek (PC-k) és az otthoni mikroszámítógépek. Pl. 1977: Apple II, 1981: IBM PC (Intel 8088 CPU-val). A mikroprocesszorok eleinte 8 bitesek (8080, Z80, Motorola 6800), majd 16 (8086, 68000), 32 bitesek (80386, 68020 stb.), végül 64 bitesek lettek. A negyedik generáció innovációi: GUI (Xerox Alto majd Apple Lisa/Mac), hálózatok (Ethernet 1973, ARPANET-ből Internet), párhuzamos számítógépek (Cray I – vector supercomputer 1976). A félvezető technológia elképesztő ütemben fejlődött: Gordon Moore megfogalmazta a Moore-törvényt (1965), miszerint a chipbe integrálható tranzisztorok száma ~18 havonta duplázódik – ezt a 4. generáció jó 30-40 évig tartotta is. E generáció végére a számítógép mindennapi eszközzé vált, az internetkorszak beköszönt, az okostelefonok megjelentek (ami lényegében zsebben hordozható számítógép).
  • Ötödik generáció (1990-es évektől napjainkig, tágabb értelemben): Gyakran ötödik generáció alatt a mesteséges intelligencia orientált számítógépek projektjét értik (Japán, 1980-as évek – PROLOG alapú gépek, parallel inference machines – végül nem hozott átütő eredményt abban a formában). Más értelmezés szerint az ötödik generáció a masszívan párhuzamos, 64 bit, objektumorientált, hálózatba kapcsolt gépek kora. Időnként ide sorolják a szuperszámítógépek modern generációit (masszív párhuzamosság tízezer processzorral), a kvantumszámítógépek kísérleteit, vagy egyszerűen a jelenlegi technológiai szintet. A mai PC-k és szerverek processzorai már sok generációnyi fejlesztést integrálnak: 64 bites többmagos CPU-k, specializált magok (GPU – grafikus processzor, TPU – tensorki gyorsító, DSP magok), óriási összevont cache-ek, pipelinok és out-of-order végrehajtás, gigahertzes órajelek. A tranzisztor-félvezető technológia a nanométeres skálán jár (2020-as években 5nm körüli csíkszélesség a legfejlettebb gyártásnál), integrálható tranzisztorok száma processzoronként több tízmilliárd. A teljesítmény szempontjából ma a hangsúly a párhuzamosságon van: nem az órajel növelésével (az 2000-es évek közepén ~3-4 GHz-nél stagnál hűtési/fizikai okokból), hanem a magszám, vektorutasítások (SIMD), GPU használat növelésével jön a fejlődés. A felhő alapú infrastruktúra is egy generációs váltás: a számítás nem egy gépben, hanem sok elosztott gép együttműködésével történik.
  • Technológiai fejlődés sarokpontok: Míg a generációkat nehéz élesen elhatárolni, általánosságban a trend a miniatürizálás, gyorsulás és olcsóbbá válás. A számítógépek teljesítménye exponenciálisan nőtt (lásd Moore-törvény), miközben az áruk drasztikusan csökkent: egy tranzisztor költsége ma gyakorlatilag elhanyagolható az 60 évvel ezelőttihez képest, megbízhatósága pedig közel tökéletes. A számítógép-architektúra terén a Neumann-elv alapvetően kitartott (bár a párhuzamos, elosztott rendszerek kihívást jelentenek, és vannak kísérletek nem-Neumann, pl. dataflow gépekre, neuromorfikus chipekre). Az utóbbi időben a specializáció felé mozdulunk: általános CPU helyett adott feladatra optimalizált architektúra (GP GPU, AI accelerator ASIC-ek, FPGA alapú adaptív rendszerek). Jövőbeli potenciális generációs ugrás lehet a kvantumszámítógép és a kvantum-algoritmusok térnyerése, de ez még egyelőre kísérleti fázisban van.
  • Összegzés generációkról:
    1. generáció: Elektroncső, nagyméretű, lassú, drága, megbízhatatlan.
    2. generáció: Tranzisztor, kisebb, gyorsabb, megbízhatóbb, megfizethetőbb nagyvállalatoknak.
    3. generáció: IC (SSI/MSI), sokkal kisebb és gyorsabb, megjelenik a család fogalma, szoftver-OS forradalom.
    4. generáció: Mikroprocesszor, PC-k, személyes számítástechnika, hálózatok, VLSI integráció.
    5. generáció: (Vita szerinti) Párhuzamos feldolgozás, AI, ultra-integráció, heterogén számítás; napjaink technológiái (ULSI, nanotechnológia, IoT) ebbe sorolhatók.