Protsessori vahemälu

**Protsessori [[vahemälu]]** (inglise k. *CPU cache*) on mälu, mida arvuti protsessor kasutab põhimällu pöördumisele keskmiselt kuluva aja lühendamiseks.

Vahemälu on põhimälust väiksem ja kiirem ning sinna kopeeritakse andmed, mida protsessor põhimälust parajasti vajab. Kui protsessor pöördub andmetele, mis on juba vahemällu kopeeritud, siis saavutatakse arvestatav ajavõit. Kui kasutatakse peamiselt vahemälu, siis on mälu keskmine pöördusaeg lähemal vahemälu pöördusajale kui põhimälu omale.

Diagramm paremal näitab kahte mälu. Iga asukoht mõlemas mälus hoiab mingeid andmeid, olenevalt mälu ehitusest võib asukoha andmete hulk olla 8–512 baiti. Vahemälu rida on tavaliselt suurem kui selle poole pöördumisel tavaliselt loetav andmete hulk, mis on tavaliselt 1–16 baiti. Igal asukohal on selle poole pöördumiseks ka unikaalne indeks. Indeksit, mis tähistab mõnda põhimälu asukohta nimetatakse aadressiks. Vahemälus on igal asukohal silt (*tag*), mis sisaldab puhverdatud andmete aadressi põhimälus. Selliseid kirjeid protsessori andmete vahemälus kutsutakse vahemälu ridadeks ehk vahemäluplokkideks.

Kui protsessor soovib lugeda või kirjutada mõnda põhimälu pesa, kontrollitakse enne kas vastav mälupesa pole juba vahemälusse kopeeritud. Selleks võrreldakse mälupesa aadressi kõigi nende vahemälu lipikutega, mis vastavat aadressi võivad sisaldada. Kui protsessor leiab, et mälupesa on vahemälus, siis on toimunud vahemälu *tabamus* (*cache hit*), pesa puudumise korral on toimunud *möödalask* (*cache miss*). Tabamuse korral kirjutab protsessor andmed otse vahemälu ritta. Tabamuste ja pöörduste suhet nimetatakse *hit rate*'iks ja sellega mõõdetakse vahemälu efektiivsust.

Kui vahemälus puudub otsitav aadress, siis suurem osa vahemäludest lisab uue kirje, kus sees on puudunud lipik ja koopia põhimälus olevatest andmetest. Protsessorile antakse andmed uuest kirjest, nagu oleks toimunud tabamus. Möödalasud on aeglased, kuna andmeid tuleb kopeerida põhimälust. Kopeerimisel toimub viivitus, kuna põhimälu on vahemälust märksa aeglasem.

## Üksikasjad
Et teha ruumi uutele sissekannetele vahemälus, tuleb tihti vahemälust mõni varem sisestatud sissekanne välja tõsta. Reeglistik, mida selleks kasutatakse, on tuntud kui *asenduspoliitika*. Peamine probleem asendusega on see, et tuleb ennustada, milline olemasolevatest vahemälu sissekannetest omab kõige vähem võimalust hiljem uuesti kasutusse minna. Tuleviku ennustamine on raske, eriti veel riistvaralisel vahemälul, mis kasutab lihtsaid reegleid, mis on programmeeritud mikroskeemidesse. Valida saab mitme asenduspoliitika vahel, kuid mitte ükski neist pole täiuslik. Üks populaarsemaid on LRU, mille puhul asendatakse kõige kauem kasutamata seisnud sissekanne.

Kui andmed kirjutatakse vahemällu, tuleb need mingil ajal kirjutada ka põhimällu. Selle kirjutamise ajastust kontrollib *kirjutamispoliitika*. Läbivkirjutamisega vahemälude korral kirjutatakse igal vahemällu kirjutamisel ka põhimällu. Tagasi kirjutamisega vahemälude puhul jäävad andmed vahemällu seniks, kuni vahemälu sissekanne välja tõugatakse.

Andmeid põhimälus, mis on kopeeritud ka vahemällu, võivad muuta ka teised allikad. Sel puhul võib vahemälus olev koopia aeguda. Vahemälu andmed võivad olla uuemad kui põhimälu omad, mille puhul põhimälu andmed muutuvad aegunuks. Sideprotokollid vahemälu korraldajad, mis hoiavad andmed kooskõlalised, on tuntud kui *seose protokoll*.

Moodsad mikroprotssesorid võivad sooritada mitusada käsku aja jooksul, mis kulub andmete kättesaamiseks mälust. Sellepärast rakendatakse erinevaid tehnikaid, et hoida protsessorit mälupöörduse ajal töös. Pentium Pro ja hilisemad Inteli arhitektuuriga protsessorid üritavad vahemälu möödalasu puhul täita vajatavatest andmetest sõltumatuid ülesandeid. Pentium 4 kasutab tehnoloogiat Simultaneous multithreading, (HyperThreading Inteli terminoloogia järgi) mis laseb teisel programmil või lõimel protsessorit kasutada, samal ajal kui esimene programm ootab andmeid põhimälust.

## Assotsiatiivsus

Eespool sai öeldud, et asenduspoliitika otsustab kuhu vahemälusse koopia salvestatakse. Kui asenduspoliitika võib vabalt valida sissekande, siis kutsutakse vahemälu *täisassotsiatiivseks*. Teine äärmus on kui põhimälu iga pesa saab asuda vaid ühes kohas vahemälus, seda nimetatakse otse vastendatud vahemäluks (diagrammil "direct mapped"). Paljud vahemälud teostavad nn kompromissi ning neid nimetatakse *moodulassotsiatiivseteks*. Näiteks esimese taseme andmevahemälu AMD Athlonis on kahes suunas assotsiatiivne, mis tähendab, et põhimälu plokki võib kopeerida kahte vahemälu asukohta.

Liigne assotsiatiivsus on halb. Kui on 16 kohta kuhu asenduspoliitika võib panna uue sissekande vahemälus, siis vahemälust sissekande otsimisel tuleb kontrollida läbi kõik 16 kohta. Suurema hulga kohtade kontrollimine nõuab rohkem transistore ning aega. Samas vahemälud suure assotsiatiivsuse astmega omavad paremat tabamustegurit, kuid neil on pikem pöördusaeg ja suurem voolutarve.

Üks otsevastendusega vahemälu eeliseid on sissekannete asukoha lihtne ja kiire leidmine. Kui virtuaalaadress on välja arvutatud, saab vahemälust juba andmeid lugeda ning protsessor võib jätkata tööd andmetega, enne kui kontrollitakse kas vahemälusse kopeeritud põhimälu aadress üldse vastab otsitud aadressile.

## Aadressi tõlkimine
Ajalooliselt esimene riistvaraline vahemälu, mida kasutati arvutis ei puhverdanud põhimälu andmeid, vaid hoopis virtuaalaadresse ning nendele vastendatud füüsilisi aadresse. See vahemälu on tuntud kui TLB (Translation Lookaside Buffer).

## Vahemälu hierarhia moodsates protsessorites
Moodsatele protsessorkiipidele on ehitatud mitmeid koostöötavaid vahemälusid.

### Spetsialiseeritud vahemälud
Käsukonveieritega protsessori kasutavad mälu mitmes punktis: käsuvõtt, virtuaalaadressi tõlkimine füüsiliseks, operandivõtt (andmete hankimine). Loomulik disain on kasutada erinevaid vahemälusid iga erineva punkti jaoks, et ükski vahemälu ei peaks teenindama kahte astet konveieris. Selletõttu on protsessoril vähemalt kolm eraldi rolliga vahemälu: andmevahemälu, käsuvahemälu ja TLB.

#### Ohvervahemälu
Ohvervahemälu on tavaliselt pisikene (kuni paar kilobaiti) täisassotsiatiivne vahemälu, mis hoiab protsessori vahemälust välja tõugatud andmeid. Ohvervahemälu on madalaima taseme vahemälu ning põhimälu vahel, hoiab ainult andmeid, mis on välja tõugatud vahemälust. Ohvervahemälu võib oluliselt vähendada liiga väikesest assotsiatiivsuse astmest tingitud möödalaskude arvu.

#### Jäljevahemälu
Üks ekstreemsemaid näiteid vahemälu spetsialiseerumisest on *jäljevahemälu*, mis on ehitatud Intel Pentium 4 mikroprotsessoritesse. Seda mehhanismi kasutatakse, et käsuvõtu kiirust suurendada. Selleks salvestatakse eelnevalt juba hangitud ja dekodeeritud käsu järjendeid. Selle mehhanismi pakkusid esimesena välja Eric Rotenberg, Steven Bennett ja Jim Smith (teadlane) oma 1996 avaldatud dokumendis "Trace Cache: a Low Latency Approach to High Bandwidth Instruction Fetching."

Jäljevahemälu salvestab käsud pärast nende dekodeerimist.

Lisalugemist: A. Toomsalu artikkel ajakirjas A & A Smithi, Rotenbergi ja Bennetti avaldatud dokument.

#### Harvardi arhitektuur
Eraldi käsu- ja andmevahemäludega mikroprotsessorit nimetatakse Harvardi arhitektuuriga protsessoriks. Algselt kasutati seda mõistet arvutite kohta, millel on andmemälu ja käsumälu eraldi, mis välistas programmi poolt käskude muutmise.

### Mitmetasemelised vahemälud
Üks suurematest probleemidest on kompromiss vahemälu pöördusaja ja tabamusteguri vahel. Suured vahemälud on aeglased kuid omavad suurt tõenäosust, et korduvalt kasutatavid andmeid ei tõrjuta vahemälust välja. Et sellest mööda pääseda kasutavad paljud mikroprotsessorsüsteemid mitmetasemelist vahemälude süsteemi. Kasutatakse väikeseid ja kiireid vahemälusid koos suurte ja aeglaste vahemäludega. Kuna protsessori ja põhimälu kiiruste vahe järjest kasvab, kasutatakse juba ka kolmeastmelisi vahemälusid. Näiteks 2003. aastal lisas Intel Itanium II 6 MB protsessorile integreeritud kolmanda taseme ühitatud vahemälu. IBM Power 4 seeriad protsessorid omavad protsessorimoodulile paigutatud 32 MB kolmanda taseme vahemälusid, mida jagavad kõik samale moodulile paigutatud 4 protsessorit.

Mitmetasemelised vahemälud opereerivad tavaliselt kontrollides väikseimat, **1. taseme** vahemälu esimesena. Kui leitakse õige sissekanne, jätkab protsessor täiskiirusel. Kui sissekannet ei leita, kontrollitakse järgmist taset, kui sissekannet vahemälust ei leita, otsitakse sissekanne põhimälust.

Mitmetasemelised vahemälud toovad hulga uusi disaininüansse. Näiteks mõned protsessorid (nagu Intel Pentium 2, 3 ja 4. Samuti ka enamik RISC protsessoreid) salvestavad 1. taseme vahemälu ka 2. taseme vahemälusse (kutsutakse sisaldavateks? vahemäludeks). Teised protsessorid (näiteks AMD Athlon) salvestavad andmed ainult ühele tasemele (kutsutakse välistavateks vahemäludeks).

Viimati nimetatud vahemälude eelis on see, et nad suudavad hoida endas rohkem andmeid. See eelis on suurem kui on tegemist suurte vahemäludega. Kui 1. tasemelt sissekannet ei leita ja 2. tasemelt leitakse siis vahetatakse 2. tasemelt rida mõne 1. taseme omaga. Vahetamine nõuab rohkem tööd kui ülekopeerimine, mida sisaldav vahemälu teeb.

Üks sisaldava vahemälu eelis on see, et kui mõni väline seade soovib eemaldada protsessorist mõne vahemälu rea, siis on vaja selleks kontrollida ainult 2. taseme vahemälu. Välistav vahemälu hierarhia nõuab ka 1. taseme kontrollimist.

Suuremad arvutid omavad tihti ka vahemälu 2. taseme ning põhimälu vahel. Seda kutsutakse 3. taseme vahemäluks. See vahemälu on tihti ehitatud protsessorist eraldi kiibi peale ja võib olla mahuga 2–256 MB. Selle lisamine maksab väga palju ja selle vahemälu eeliseid on rohkem näha suurte andmehulkade juures, mida kohtab põhiliselt serverarvutite juures. Selle vahemälu maksumus on põhjus, miks PC protsessorid ei oma sellist vahemälu.

### Näide: K8
Et illustreerida spetsialiseeritud ja mitmetasemelist vahemälu, on siin välja toodud AMD Athlon 64 mälu alamsüsteemi hierarhia, mille tuuma disain on tuntud kui K8. (detailid siin):

K8-l on 4 spetsialiseeritud vahemälu: käsuvahemälu, käsu-TLB, andme-TLB ja andmevahemälu. Need vahemälud on kõik kohandatud oma ülesande jaoks

* Käsuvahemälu hoiab koopiaid 64 baidi pikkustest mäluridadest ja väljastab 16 baiti taktis. Iga bait selles vahemälus on salvestatud kümne bitina, lisabitid märgivad käskude piire (see on näide eeldekodeerimisest). Sellel vahemälul on ainult paarsuskaitse, ECC (Error-correcting code) kaitset ei kasutata. Põhjus on selles, et võrdsuskaitse on lihtsam ja kahjustatud andmed saab asendada värske koopiaga mälust (käsuvahemälu ei ole protsessori tuuma jaoks kirjutatav).
* Käsu-TLB hoiab koopiaid operatsioonisüsteemi lehetabeli sissekannetest (PTE-d). Iga takti käsuvõtt omab oma virtuaalaadressi, mis tõlgitakse läbi selle TLB füüsiliseks aadressiks. Iga sissekanne on kas 4 (32-bitises režiimis) või 8 (64-bitises režiimis) baiti mälus. Iga TLB on jagatud kahte sektsiooni, üks PTE-de jaoks, mis salvestavad 4 kB lehtede aadresse, ja teine PTE-de jaoks, mis hoiavad 4 MB või 2 MB lehtede aadresse.
* Andme-TLB-l on kaks koopiat, mis hoiavad identseid sissekandeid. Need kaks koopiat võimaldavad ühes taktis kahe virtuaalaadressi füüsiliseks tõlkimist. Nagu käsu-TLB on ka see TLB jagatud kaheks.
* Andmevahemälu hoiab koopiaid 64-baidistest mäluridadest. See on jagatud 8 osa vahel (iga osa hoiab 8 kB andmeid) ja on võimeline väljastama kaks 8-baidist andmesõna taktis, eeldusel et need andmed on eri osades.

## Vaata ka
*Lehekülgede saalimine

## Välislingid
*[ftp://ftp.cs.wisc.edu/markhill/Papers/toc89_cpu_cache_associativity.pdf Evaluating Associativity in CPU Caches] – Hill and Smith – 1989 – Introduces capacity, conflict, and compulsory classification.
*Cache Performance for SPEC CPU2000 Benchmarks – Hill and Cantin – 2003 – This reference paper has been updated several times. It has thorough and lucidly presented simulation results for a reasonably wide set of benchmarks and cache organizations.