Cache, Cache és harmadszor is Cache Napjainkban, a XXI. században bátran kijelenthetjük, hogy a számítógépek korát éljük. A digitális rendszerek mára a modern ember életének meghatározó szereplőjévé váltak. Elég, ha csak arra gondolunk, hogy ma a legtöbb háztartásban megtalálható legalább egy, de jellemzően több számítógép is. Persze, természetesen nélkülük sem elképzelhetetlen és lehetetlen az élet, de ha feltennénk magunknak a kérdést, mit csinálnánk számítógépek nélkül, mi lenne velünk, hogyan élnénk, hol tartanánk most, ne biztos, hogy olyan egyértelmű lenne a válasz. De hogyan is működnek ezek a számítógépek? Erre a kérdésre természetesen rengeteg forrásból beszerezhetjük a megfelelő válaszokat, könnyebben, vagy nehezebben. Akit egy kicsit nagyobb mélységeiben is foglalkoztat ez a téma, biztosan találkozott már a gyorsítótár (idegen szóval cache) fogalmával. Ellenben ha meg is szeretné érteni a működését, akkor már nehezebb dolga lesz. Sajnos azt tapasztaltam, hogy meglehetősen kevés - főleg magyar nyelven íródott - jól összeszedett, "halandó emberek nyelvén" megfogalmazott dokumentum érhető el a témában, így aztán elhatároztam, hogy megpróbálok létrehozni egy ilyet. Itt a végeredmény látható. A dokumentum az oldalon letölthető formában is elérhető, és feltételez némi alapszintű ismereteket a számítógép felépítésével és működésével kapcsolatban. Őszintén remélem, hogy minden kedves érdeklődőnek a hasznára válik! Kellemes olvasgatást, jó tanulást! A készítő: Oroszi Dániel
Türelem, CPU... Mint tudjuk, a számítógép a következőképpen működik: a processzor bemenetként utasítások és a hozzájuk tartozó adatok sorozatát kapja, ezeket az adott célnak megfelelően feldolgozza, majd kimenetként valahová továbbítja. Ezeket az adatokat a CPU a központi memóriából olvassa be. Ezzel viszont az a probléma, hogy a RAM úgynevezett "felejtő" tároló, azaz csak addig őrzi meg a benne tárolt adatokat, ameddig feszültség alatt áll, tehát a számítógép kikapcsolásával egyidejűleg mindent "elfelejt". Ez így nem túl hatékony, így szükségünk van egy olyan adattároló egységre, amely "nem felejtő". Ilyen tároló például a winchester, amit a mai számítógépek többsége használ. Felmerülhet a kérdés, hogy akkor a processzor miért nem rögtön a winchesterből tölti be az adatokat, miért van szükség
a RAM-ra? A válasz egyszerű: Az utóbbi időben a processzorok rohamos fejlődésnek indultak, mellyel a merevlemezek már csak pusztán felépítésükből adódóan sem tudtak lépést tartani. Gondolok itt elsősorban ezeknek az eszközöknek a sebességére, illetve arra, hogy egy mechanikusan működő merevlemez nem is lehetne olyan gyors, mint egy teljesen elektronikusan működő processzor. Ezért van tehát szükség a RAM-ra, amely a winchester és a processzor között foglal helyet a számítógép-architektúrában. A probléma azonban az, hogy bár ez az eszköz már jóval gyorsabb, mint a merevlemez, még mindig sokkal lassabb, mint a CPU. Ez azt jelenti, hogy amikor a processzor valamilyen adatot kér le a memóriától akkor várnia kell, amíg a lassabb memória a kívánt adatot előkeresi esetleg lekéri a winchestertől -,majd átadja a processzornak feldolgozásra. Ez a várakozási idő jelentősen redukálja a rendszer teljesítményét és hatékonyságát, tehát gyakorlatilag lehet a processzorunk bármilyen gyors, a vele együttműködő lassabb memória le fogja húzni az "ő szintjére". Ezt kiküszöbölendő egy további gyorsabb memóriatípust építettek a memória és a processzor közé, ezt nevezzük cache-nek. Háromféle cache-ről beszélhetünk: az úgynevezett "off-chip" cache, melyet a winchesterben helyeznek el annak gyorsításának céljából, a szoftveres cache, például a UNIX operációs rendszer vagy a webböngészők esetében, illetve az "on-chip" cache a CPU és a RAM között. Ennek az oldalnak az utóbbi "on-chip" cache a témája. Cache, cache és harmadszor is cache...
Dynamic RAM, Static RAM Az a memóriatípus, amelyet a mai számítógépek többségében használunk, amelyet egyszerűen csak RAM-ként ismerünk, pontos megnevezése alapján valójában Dynamic RAM (DRAM). A DRAM előnye, hogy nagyon kicsi alkatrészekből (kondenzátorokból) áll, amiből az következik, hogy kis helyen is viszonylag nagy mennyiségű adatot tud tárolni. Hátrányuk ellenben pontosan ebből következik, mivel ezek az apró kondenzátorok időnként újratöltésre szorulnak, amit frissítésnek nevezünk. Ezalatt a frissítési idő alatt azonban a memória se nem olvasható, se nem írható. Előállítása olcsó, energiaigénye alacsony, azonban többek között az előbb felvázolt probléma miatt is működése lassú. A másik típus, a Static RAM (SRAM) ezzel ellentétben képes olyan gyors működésre, mint a processzor. Ez a tulajdonsága elsősorban felépítéséből adódik. A DRAM-mal szemben ugyanis nem kondenzátorokból, hanem olyan áramköri egységekből áll, melyek nem igénylik a DRAM-nál említett frissítést. Akkor miért nem használunk ilyen SRAM-okat a megszokott DRAM-ok helyett? A válasz az SRAM hátrányaiban rejlik. Azok az
áramkörök, melyekből egy ilyen statikus RAM áll, sokkal több helyet igényelnek, mint a DRAM kondenzátorai, ezáltal egy ugyanakkora helyen sokkal kisebb tárolókapacitást lehet belőlük kihozni. Ezen felül előállításuk is drága és a magas hőtermelésük miatt hűtésük is igencsak energiaigényes.
Tulajdonság
Dynamic RAM (DRAM)
Static RAM (SRAM)
Tároló egység
Kondenzátorok
un. flip-flop áramkörök
Átviteli sebesség
Lassabb, mint a CPU
Képes a CPU sebességére
Időbeli késés
Magas
Alacsony
Hely/tárolókapacitás arány
Magas
Alacsony
Energiaigény
Alacsony
Magas
Ár
Olcsó
Drága
Mi lenne akkor a tökéletes megoldás? Ötvözni kellene a két típusú memória előnyeit. Ennek a gondolatnak az eredményeként született meg az az elgondolás, miszerint használjunk a számítógépekben alapvetően DRAM-ot, de építsünk be még mellé kis mennyiségű SRAM-ot is a sebesség fokozása érdekében. Ezt a kis mennyiségű SRAM-ot nevezzük cache-nek.
Cache történelem Az egész történet 1985-ben, az Intel 386DX processzorával kezdődött. Eleinte a cache ténylegesen a processzor és a központi memória között helyezkedett el.
Habár az akkori CPU-k támogatták a cache memória használatát, megléte csupán opcionális volt és teljes mértékben az alaplap gyártójától függött. Természetesen a cache memória nélküli rendszerek jóval lassabbak voltak, mint a gyorsítótárral szerelt társaik, így aztán az alaplapgyártó cégek is hamar belátták, hogy modern alaplap nem létezhet gyorsítótár nélkül. Ebben a kezdeti időszakban a cache memóriák tipikus mérete csupán 64-128KB volt. 1989-ben, az Intel a 486DX processzorába már integrált egy 8KB-os belső cache memóriát. Innentől kezdve sorolhatjuk a cache memóriákat két csoportba a processzortól való távolságuk alapján. A CPU-ba beépített belső gyorsítótárat L1 (Level 1), míg a külsőt L2 (Level 2) cache-nek nevezzük. A külső memória megléte még mindig az alaplap gyártójától függött, de ebben az időben már jellemzően minden alaplapon megtalálható volt. Tipikus méretük 128 és 256KB volt. Az első Pentium processzorral az Intel kétfelé választotta a belső gyorsítótárat. Létrehozott egy utasítás cache-t és egy adat cache-t. Ezekről bővebben majd később. A külső cache tipikus mérete ebben az időben 256 és 512KB volt. A külső cache-el azonban volt egy probléma. A processzor ugyanis úgy működik, hogy a belső sebessége gyorsabb, mint a külső, így az L2 cache elérése lassabb volt, mint az L1 cache esetében. Ezt orvosolandó az Intel a P6 architektúrával 1995-ben integrálta az L2 cache-t is a CPU-ba. Mai napig ez a felépítés használatos. Mind az L1, mind az L2 cache a CPU-n belül található meg. A gyorsítótár típusa és mérete így most már kizárólag a processzor típusától függ.
A cache memória felépítése és elhelyezkedése Ahogyan azt az előző részben már említettem, a cache memória mára teljes egészében a CPU részévé vált. Az alábbi képen egy egyszerű egymagos processzor felépítése látható. Jogos kérdés lehet, hogy amennyiben már mind az L1, mind az L2 cache a processzoron belül található, akkor miért nevezzük őket egyáltalán kétféleképpen? Fontos tudni, hogy az L2 cache mérete mindig nagyobb, mint az L1 cache-é. Az L1 cache kettéosztásával már beszéltünk. Ahogyan az talán az ábrán is látszik, az L1 utasítás cache egyfajta bemeneti gyorsítótárként szolgál, míg az adat cache a memóriába visszaírandó - a processzor által már feldolgozott - adatokat tárolja. A többi nem említett egységről a következő részben fog szó esni. A gyártók sokféleképpen szokták megadni ennek az L1 cache-nek a méretét. Van, amikor konkrétan leírják a két L1 cache méretét egyértelműen, de olyan is előfordulhat, hogy a vásárlónak találgatnia kell. Segítségül szolgáljon, hogy az utasítás és az adat cache mérete az esetek túlnyomó részében megegyezik. Egymagos processzorok
esetében az L2 cache elhelyezkedése egyértelmű. Egy maghoz egy L2 cache tartozik. Többmagos processzorok esetében azonban ez a kérdés nem teljesen egyértelmű. Az AMD processzorainál például minden maghoz külön L2 cache tartozik. Az Intel szerint azonban ez nem elég hatékony. Az Intel kétmagos processzorai úgy készülnek, hogy a két mag közösen használ egy darab megosztott L2 cache-t. Ha belegondolunk, ez valóban hatékonyabb, mint az AMD megoldása, amit a következő példán keresztül könnyen be is láthatunk. Tegyük fel, hogy van egy kétmagos CPU-nk, magonként egy-egy 2MB-os L2 cache-el. Egy adott feladat elvégzése során az egyiknek 3,5MB-ra lenne szüksége, míg a másik csak 0,5MB-ot használ. Ebben az esetben az első mag kénytelen a központi memóriához fordulni, pedig a másik mag cache-e pont rendelkezik még 1,5MB szabad hellyel, de sajnos nem férhet hozzá. Ha ez a cache megosztott lenne a két mag között - és így 4MB-os lenne -, ez a probléma megszűnne. Négymagos processzor esetében még nem ennyire előrehaladott a helyzet, de ott is létezik a megosztott cache elve. Itt két magonként van egy-egy darab megosztott cache. Az Intel tervezi a jövőben a négy mag - egy cache párosítást is. Érdekességképpen jegyezzük meg, hogy az AMD egyik architektúrájában egy olyan rendszert használ, miszerint minden maghoz egy cache tartozik, de ezeket összefogja egy harmadik megosztott cache (L3 cache). A cache belső felépítése a következőképpen néz ki: úgynevezett sorokra van felosztva, melyek az adatokat tárolják. A gyorsítótár egységesen van felosztva, azaz minden egyes sor tárolókapacitása azonos. Elég jellemző például a 64 byte-os sorok használata. Tehát például egy 512KB-os L2 cache esetében ez 8192 sort jelentene. Ezeknek a használatáról a későbbiekben fogunk beszélni.
A cache memória működése Bekapcsoljuk a számítógépet. A winchesterről betöltődnek a szükséges adatok a központi memóriába. Amikor a CPU-n belül található "fetch" egység valamilyen adatot kérvényez a processzor számára, először a cache memóriában keresi. Ha ott nem találja, akkor fordul a központi memóriához. Amikor a központi memória kiadja a processzornak az igényelt adatokat, a cache memória vezérlő áramkörei megpróbálják "kitalálni", hogy mi lehet a következő utasítás, adat, amire a CPUnak szüksége lesz, és azt előre átmásolja a RAM-ból, így a processzornak a következő alkalommal már elég csak a cache-hez fordulnia a szükséges adatokért. A cache vezérlő általában a soron következő memóriablokkot másolja át a RAMból, feltételezve az utasítások szekvenciális végrehajtását. Ilyen programok esetében nincs is gond, hiszen a CPU-nak sosem kell közvetlenül a RAM-hoz
fordulnia. De mi a helyzet akkor, ha a program nem szekvenciálisan fut? Például ciklusokat használ, vagy időről időre ugrál ide-oda az utasítások között. Ez jelenti a cache memória számára az igazi feladatot. Természetesen létezik erre a feladatra egy "előrejelző" rendszer, de ahogy az időjárás-előrejelzés, ez sem lehet teljesen pontos. A mai modern processzorok átlagos találati aránya körülbelül 80%, azaz az esetek 80%-ban megtalálható más a cache memóriában a CPU számára szükséges adat, utasítás, így nem kell a központi memóriához fordulnia, nem lassul a rendszer.
A memórialeképezés módszerei Memórialeképezésnek nevezzük azt a folyamatot, illetve azt a logikát, melynek alapján a cache memória hozzárendeli egyes sorait a központi memória meghatározott blokkjaihoz. Ez nyílván azért fontos, mert a CPU elsődlegesen a keresett adat központi memóriabeli címével fog az adatra hivatkozni, a cache-nek pedig tudnia kell, hogy ehhez a címhez a cache melyik része van hozzárendelve. (Egyébként ezt a "címfordítást" végzi a CPU dekódoló egysége.) Így tudja eldönteni, hogy a keresett adat egyáltalán megtalálható-e a gyorsítótárban, avagy sem. Gyakorlatilag ez a folyamat a gyorsítótárazás lelke. Az idők során három memórialeképezési konfiguráció alakult ki, nézzük meg őket sorban. Az első módszer a közvetlen hozzáférés nevet viseli. Ezt a típusú cache memóriát a legegyszerűbb és a legolcsóbb előállítani. Lényege, hogy a gyorsítótár pontosan annyi sorra van felosztva, amennyi blokkra a RAM. Ezzel azonban az a probléma, hogy a cache sorai mindig kisebb tárolókapacitással rendelkeznek, mint a RAM blokkjai, így aztán nem lehet beszélni egyértelmű hozzárendelésről és így a gyorsítótár átlagos találati aránya is csökken. Ez a legkevésbé hatékony módszer, ezért nem használjuk. A következő módszer a teljesen asszociatív memórialeképezés. Ennél a módszernél nincs a RAM blokkjai és a cache sorai között egyértelmű hozzárendelés, így gyakorlatilag a központi memória bármelyik része kerülhet a cache bármelyik részébe. Ezzel megszűnik a fentebb említett hozzárendelési probléma és valóban ez a leképezési konfiguráció a leghatékonyabb a három közül. A probléma azonban az, hogy a bonyolult felépítése miatt ennek a cache memóriának az előállítása drága, így ezt a módszert sem használjuk. Ismételten egy köztes megoldásra lenne szükség, amit n-utas csoport-asszociatív memória leképezésnek nevezünk. Ennek lényege, hogy a cache sorait csoportokba osztjuk. Minden csoportban n darab sor található és a RAM-ot szintén ilyen struktúrájú blokkokra osztjuk. Ennek előnye, hogy nem annyira bonyolult, mint a
sima asszociatív megoldás, így olcsóbb is, de közben hatékony, mivel a csoportokban lévő sorok a teljesen asszociatív leképezés elvén működnek. Ez tehát a ma létező legjobb memórialeképezési konfiguráció, ezt használják a mai számítógépekben.
Forrás: http://www.hardwaresecrets.com/article/481 - 9 oldalas angol nyelvű dokumentum feldolgozva.