KES MEMORIJA
============

(Za vise detalja, procitati Dandamudi, str. 693-733, Tanenbaum
 str. 77-80,293-299, Hamacher, str. 290-305)

*) Kes memorija se koristi kako bi se prevazisla razlika u brzini
   izmedju procesora i operativne (RAM) memorije. Ideja je da se
   kopije podataka koji se najcesce koriste (ili za koje postoji
   pretpostavka de ce uskoro biti potrebni) drze u brzoj statickoj
   memoriji kako bi se ubrzao rad procesora.

*) Kes memorija je sporija od registara procesora, ali je znacajno
   brza od operativne memorije, s obzirom da se izradjuje kao staticka
   memorija (zasnovana na flip-flop-ovima, pa ima manje kasnjenje),
   kao i da je znatno manjeg kapaciteta, pa joj se brze pristupa.

*) Princip rada kes memorije zasniva se na PRINCIPU LOKALNOSTI:

   -) PRINCIP VREMENSKE LOKALNOSTI: ukoliko se neki podatak cesto
   koristio u prethodnom periodu, velika je verovatnoca da ce uskoro
   ponovo biti koriscen. Sa druge strane, podaci koji dugo nisu bili
   korisceni verovatno nece biti ni u narednom periodu.

   -) PRINCIP PROSTORNE LOKALNOSTI: ukoliko se neki podatak koristi u
   nekom trenutku, velika je verovatnoca da ce njemu susedni podaci
   biti korisceni u bliskoj buducnosti. Ovo je tacno i za podatke
   (npr. pristup elementima istog niza, ili poljima iste strukture),
   ali i za instrukcije (najcesce se instrukcije izvrsavaju jedna
   za drugom).

   Primer:

   S = 0;
   for(i = 0; i < 100; i++)
    for(j = 0; j < 100; j++)
     S += a[i][j];

   Prostorna lokalnost se ogleda u pristupu instrukcijama koje se
   nalaze na susednim lokacijama u memoriji (isto vazi i za elemente
   matrice). Vremenska lokalnost se ogleda u ponovljenom pristupu
   instrukcijama petlje, kao i promenljivoj S.

*) Kes memorije koriste princip prostorne lokalnosti tako sto kada
   procesor zahteva neki podatak (ili instrukciju), vrsi se kopiranje
   citave okoline tog podatka u kes, jer je pretpostavka da ce susedni
   podaci biti uskoro korisceni. Ucitavanje bloka podataka iz memorije
   u kes se obavlja znatno efikasnije nego ucitavanje pojedinacnih
   podataka, imajuci u vidu karakteristike i nacin rada dinamickih
   memorija. Sa druge strane, princip vremenske lokalnosti ostvaruje
   se tako sto se podaci koji su nedavno korisceni nalaze u kesu, jer
   je pretpostavka da ce uskoro ponovo biti korisceni. Ovo se postize
   odgovarajucom politikom zamene kesiranih podataka: kada se kes
   napuni, tada se pri sledecem ucitavanju iz njega brisu oni podaci
   za koje postoji pretpostavka da nece uskoro biti korisceni (to su
   obicno oni podaci koji najduze nisu bili korisceni u prethodnom
   periodu).

*) Za potrebe komunikacije izmedju kes memorije i operativne memorije,
   pretpostavljamo da je operativna memorija podeljena na blokove
   susednih bajtova fiksirane duzine koje nazivamo KES-BLOKOVIMA.
   Pretpostavimo da je duzina jednog takvog bloka 32 bajta (tako je,
   npr. na Pentium procesorima). Svaki kes-blok, dakle, pocinje na
   adresi deljivoj sa 32. Kes memorija je takodje podeljena na blokove
   iste duzine koje nazivamo LINIJAMA KESA. Svaka linija kesa ima
   svoju adresu, tj. redni broj pocev od nule. Prilikom transfera
   podataka iz memorije u kes, uvek se ucitava ceo kes-blok koji
   sadrzi trazeni podatak u neku od slobodnih linija kesa (dakle,
   kes-blok igra ulogu okoline nekog podatka).
   
*) Kada procesor zahteva citanje nekog podatka sa date adrese u
   operativnoj memoriji, najpre se proverava da li se dati podatak
   (tj. odgovarajuci kes-blok) nalazi u nekoj od linija kesa. Ukoliko
   se nalazi, dohvata se podatak iz te linije kesa i prosledjuje
   procesoru (ovakav scenario se zove i POGODAK KESA, engl. CACHE
   HIT).  Ukoliko se ne nalazi, tada je potrebno najpre podatak
   dohvatiti iz memorije (zajedno sa celim njegovim kes-blokom) i
   prebaciti u kes, a zatim podatak iz kesa dostaviti procesoru
   (ovakav scenario se naziva PROMASAJ KESA, engl. CACHE MISS). Ako sa
   C oznacimo vreme pristupa kesu, a sa M vreme pristupa memoriji (M
   je znatno vece od C), tada je ocekivano vreme pristupa C + (1 -
   H)*M, gde je H verovatnoca da je podatak u kesu (tzv. verovatnoca
   pogodka, engl. cache hit ratio). Ako bi H bio 1, tada bi vreme
   pristupa bilo jednako C. Naravno, ovo nije realno, zato sto je kes
   znatno manji od operativne memorije i ne moze sadrzati sve podatke
   iz memorije. Ukoliko je H = 0, tada je vreme pristupa jednako C + M
   (najgori moguci slucaj). Parametar H zavisi od velicine kesa (veci
   kes ima vece H) ali i od toga na koji nacin program koristi
   podatke, tj. u kojoj meri koristi princip lokalnosti. U praksi moze
   dostici i 99%. Vremenska cena promasaja kesa (tj. vreme M potrebno
   da se podatak dohvati iz memorije i prebaci u kes) se cesto naziva
   i KAZNA PROMASAJA (engl. CACHE PENALTY).

*) U slucaju dohvatanja kes-bloka iz memorije, moze se dogoditi da je
   kes vec prepunjen, tj. da nema slobodnih linija kesa (ili makar
   nema slobodnih linija kesa u koje se dati kes-blok moze upisati,
   zavisno od organizacije kesa). U tom slucaju se vrsi ZAMENA LINIJE
   KESA.  Ovo podrazumeva da se neka od linija kesa izbacuje iz kesa,
   da bi se oslobodio prostor za trazeni kes-blok. POLITIKA ZAMENE
   definise nacin na koji se bira linija koja ce biti zamenjena i
   veoma je vazna zbog dobrog iskoriscenja vremenske lokalnosti. O
   politikama zamene bice nesto vise reci kasnije.

*) Kada procesor zahteva pisanje u memoriju, obicno postoje dve
   POLITIKE PISANJA koje se primenjuju:

   -) Write-Back: kod ove politike, ukoliko se podatak nalazi u kesu,
   tada se azurira samo kopija iz kesa, dok se fizicki upis u memoriju
   ostavlja za kasnije, kada odgovarajuca linija kesa bude bila
   zamenjena, tj. izbacena iz kesa (naravno, upis se vrsi samo ako je
   linija menjana u medjuvremenu, tj. ako nije sinhronizovana sa
   originalnim podatkom iz memorije; ovo se obicno u kes memoriji
   oznacava tzv. "prljavim bitom", engl. dirty bit). Ukoliko podatak
   nije u kesu, tada se obicno ucitava odgovarajuca linija u kes, gde
   se zatim vrsi azuriranje promenjenog podatka.

   -) Write-Through: kod ove politike, uvek se vrsi upis direktno u
   memoriju (a ako se nalazi i u kesu, tada se azurira i kopija u
   kesu). Ovaj pristup je nesto sporiji, ali je cesto jednostavniji za
   implementaciju.

*) ORGANIZACIJA KESA

   Organizacija kesa se odnosi na nacin preslikavanje adresa iz RAM-a
   u adrese u kesu.

   1) DIREKTNO MAPIRANJE

    -) Kod direktnog mapiranja, adresa trazenog podatka u operativnoj
       memoriji se deli na tri dela:

       ADRESA:  |   TAG   |   BROJ_LINIJE |  POMERAJ |

       POMERAJ predstavlja redni broj bajta unutar linije kesa (kes-bloka).
       Ako pretpostavimo da kes-blok ima 32 bajta, tada polje POMERAJ ima
       5 bita.

       BROJ_LINIJE predstavlja redni broj linije kesa u kes memoriji. Ako
       pretpostavimo da kes ima 1MB (= 2^20 bajta = 2^15 kes linija), tada
       imamo 2^15 kes linija, pa je potrebno rezervisati 15 bitova za
       polje BROJ_LINIJE.

       TAG predstavlja ostatak adrese (u nasem primeru, sadrzi 12 bitova, pod
       pretpostavkom da imamo 32-bitni adresni prostor).

    -) Svaka od linija kesa u kes memoriji sadrzi deo za podatke
       (velicine 32 bajta), deo za TAG (velicine 12 bita) i dodatni
       bit koji odredjuje da li ta linija kesa trenutno sadrzi neke
       validne podatke iz memorije (tzv. validni bit, engl. valid
       bit).  U slucaju Write-Back politike upisa, postoji i dodatni,
       tzv.  "prljavi bit" (engl. dirty bit) koji odredjuje da li su
       podaci u toj liniji menjani u odnosu na originalnu kopiju iz
       glavne memorije.

       LINIJA KESA:
       
       | Prljavi_bit | Validni_bit |   TAG(12bita)   |   PODACI(32bajta) |


    -) Prilikom zahtevanja podatka sa neke adrese, ova adresa se
       razbija na gore opisana tri dela. Zatim kes memorija proverava
       liniju kesa na odgovarajucem broju datom poljem
       BROJ_LINIJE. Ako je odgovarajuci validni bit jednak 0, tada je
       ta linija prazna, pa imamo promasaj kesa. Podatak se dovlaci iz
       memorije i upisuje u tu liniju kesa, a validni bit se postavlja
       na 1. Zatim se podatak iz te linije kesa prabacuje u procesor.
       Ako linija nije prazna, tada se TAG polje adrese trazenog
       podatka uporedjuje sa TAG poljem u toj liniji kesa. Ako se ova
       dva polja poklapaju, imamo pogodak kesa i podatak se prenosi u
       procesor. U suprotnom, imamo promasaj kesa i neophodno je
       izvrsiti zamenu linije kesa (u slucaju Write-Back politike,
       najpre se tekuca linija kesa mora sacuvati u operativnu
       memoriju, ako je prljavi bit jedinica, a zatim se u liniju kesa
       ucitava novi kes-blok). Konkretnom podatku u okviru linije kesa
       pristupa se na osnovu polja POMERAJ u adresi trazenog podatka.

    -) U direktnom mapiranju svaki kes-blok iz memorije se moze
       nalaziti u tacno jednoj kes liniji. Zbog toga je pretraga u
       kesu veoma jednostavna i brza (kombinatorna logika zahteva samo
       jedan komparator koji poredi dva TAG polja). Losa strana ovog
       pristupa je sto kes-blokovi cije adrese imaju isto polje
       BROJ_LINIJE ne mogu biti istovremeno u kesu, jer bi morali da
       budu u istoj liniji kesa. U nasem primeru, to su kes-blokovi
       koji pocinju na adresama A1 i A2 takvim da je A1 - A2 deljivo
       sa 2^20 (na primer, kes-blok na adresi 0 i kes blok na adresi
       2^20 nece moci da budu istovremeno u kesu). Ovo obicno nije
       problem, jer su takvi kes-blokovi dovoljno udaljeni u memoriji
       da ce retko postojati potreba da istovremeno budu prisutni u
       kesu, imajuci u vidu princip lokalnosti. Ipak, u nekim
       aplikacijama upravo se desavaju ovakvi slucajevi (npr. imamo
       matricu cije su vrste velicine 1MB, i zelimo da iteriramo kroz
       elemente u prvoj koloni).

   2) ASOCIJATIVNO MAPIRANJE

    -) Kod ovog mapiranja svaki kes-blok moze da ide u svaku liniju kesa.
       Adresa se sada deli na dva dela:

       ADRESA:   |     TAG    | POMERAJ |

       gde je POMERAJ redni broj bajta u kes-bloku (5 bita u nasem primeru)
       a TAG je ostatak adrese (27 bita u nasem primeru).

    -) Linija kesa sada ima strukturu:

       | Prljavi_bit | Validni_bit |  TAG(27bita) | PODACI(32bajta) |

    -) Kada se zahteva pristup podatku sa neke adrese, potrebno je
       uporediti TAG polja svih linija kesa ciji je validni bit 1 sa
       TAG poljem iz adrese trazenog podatka. Ovo zahteva veliki broj
       komparatora (2^15 u nasem slucaju, za svaku liniju kesa po
       jedan). Ako se pronadje poklapanje, imamo pogodak kesa. Ukoliko
       ne pronadjemo trazeni kes blok, imamo promasaj kesa. Tada se
       bira bilo koja prazna kes-linija i u nju se ucitava trazeni
       kes-blok.

    -) Dobra strana ovog pristupa je fleksibilnost, jer svaki kes-blok
       moze da ide u svaku kes liniju, sto teorijski daje najbolje
       iskoriscenje kes memorije. Losa strana je skupa pretraga
       kes-bloka unutar kes memorije. Takodje, losa strana je to sto
       se zahteva slozenija logika za implementaciju politike zamene
       -- jer sada imamo vise kandidata za zamenu, za razliku od
       direktnog mapiranja gde je uvek postojala samo jedna linija
       koju je trebalo zameniti (upravo ta u koju trazeni kes-blok
       mora da ide).

  3) SET-ASOCIJATIVNO MAPIRANJE

     -) Kompromis izmedju prethodna dva: kes linije se dele na skupove
        susednih linija. Ukoliko ti skupovi sadrze po dve linije, ovo
        se zove dvostruko SET-ASOCIJATIVNO MAPIRANJE (slicno za 4, 8,
        16, itd.). U praksi se najcesce koriste dvostruko i
        cetvorostruko set-asocijativno mapiranje. Svaki kes-blok sada
        moze da ide u tacno jedan od skupova linija (tj. u bilo koju
        liniju iz tog skupa). To znaci da kod dvostrukog
        set-asocijativnog mapiranja svaki kes-blok moze da ide u jednu
        od dve linije kesa koje pripadaju unapred fiksiranom skupu. Na
        ovaj nacin se zadrzava jednostavnost direktnog mapiranja (uz
        malu dodatnu cenu u pretrazi unutar skupa), a sa druge strane
        se delimicno resava problem istovremenog postojanja u kesu za
        bilo koja dva (ili cetiri u slucaju cetvorostrukog mapiranja)
        kes-bloka.

     -) Adresa se u ovom slucaju deli na tri dela kao i kod direktnog
        mapiranja. Ako opet pretpostavimo da imamo 1MB kes memorije i
	32-bitni adresni prostor sa kes-blokovima velicine 32 bajta,
	kao i da koristimo cetvorostruko set-asocijativno mapiranje,
	imacemo adresu sledece strukture:

	ADRESA:  |   TAG |  BROJ_SKUPA | POMERAJ |

	pri cemu je POMERAJ velicine 5 bita, broj skupa je velicine 13
	bita (jer imamo 2^13 skupova od po 4 linije, ukupno 2^15
	linija), i TAG ce sadrzati 14 bita. Kes linija ima sledecu
	strukturu:

	| Prljav_bit | Validni_bit |  TAG(14bita) | PODACI(32bajta) |


     -) Kada procesor zahteva podatak sa neke adrese, najpre se iz te
	adrese izdvaja BROJ_SKUPA i odlazi se na skup sa tim rednim
	brojem. Za svaku od 4 linije u tom skupu se vrsi provera
	validnog bita i ako je taj bit 1 vrsi se poredjenje TAG
	komponente adrese sa TAG-om te linije kesa. Ako pronadjemo
	poklapanje, imamo pogodak kesa i uzimamo bajt ciji redni broj
	odgovara komponenti POMERAJ iz adrese trazenog podatka. Ako to
	nije slucaj, imamo promasaj kesa i tada se vrsi ucitavanje
	kes-bloka u neku od slobodnih linija kesa u tom skupu. Ako ni
	jedna od linija u skupu nije slobodna, sprovodi se zamena
	linija kesa u skladu sa odabranom politikom.

     -) Iako je implementacija set-asocijativnog mapiranja nesto
        komplikovanija nego kod direktnog mapiranja, ona je ipak
        znatno jednostavnija nego kod potpuno asocijativnog
        mapiranja. Pretraga u kesu je znatno jednostavnija, jer
        zahteva proveru samo nekoliko linija kesa, dok je
        implementacija politike zamene takodje jednostavnija, jer
        imamo manji broj potencijalnih kandidata za zamenu. Dakle,
        set-asocijativno mapiranje predstavlja dobar kompromis izmedju
        dve krajnosti, i zbog toga je ovo danas najcesce koriscena
        varijanta organizacije kesa.

*) POLITIKE ZAMENE: U slucaju direktnog mapiranja, nema potrebe ni za
   kakvim politikama zamene, jer je jednoznacno odredjeno u koju
   liniju kesa odgovarajuci kes-blok mora da ide, pa je jasno i koja
   linija kesa se mora isprazniti. U slucaju asocijativnog mapiranja
   politika zamene treba da odabere jednu kes liniju iz skupa svih kes
   linija u kesu. U slucaju set-asocijativnog mapiranja, tada je
   potrebno odabrati jednu kes liniju iz odgovarajuceg skupa linija
   u koje dati kes-blok mora da ide. Slede neke cesto koriscene
   politike zamene:

   -) LRU (Least Recently Used): zamenjuje se ona linija kesa koja
      najduze nije bila koriscena. Ova politika obicno daje najbolje
      rezultate, jer u najvecoj meri koristi princip vremenske
      lokalnosti. Medjutim, mana joj je teska implementacija, narocito
      u slucaju asocijativnog mapiranja. Naime, ako imamo n kes-linija
      koje su kandidati za zamenu, tada je potrebno sve vreme
      odrzavati poredak vremena poslednjeg pristupa, kako bismo znali
      koja od njih najduze nije koriscena. Kada god se neka kes linija
      koristi, tada se ona u tom poretku postavlja na pocetak, dok
      ostale kes linije ostaju u dotadasnjem medjusobnom poretku.  Ovo
      se moze implementirati kao konacni automat gde svaki od n!
      mogucih poredaka predstavlja jedno stanje. Npr. za n = 4 imacemo
      4!=24 stanja koja odgovaraju svim mogucim permutacijama brojeva
      0,1,2,3 (redni brojevi kes linija u skupu). Ukoliko smo u stanju
      0,1,2,3 i pristupimo liniji 2, tada ona dolazi na pocetak, tj.
      prelazimo u stanje 2,0,1,3. Ako sada pristupimo liniji 1,
      dolazimo u stanje 1,2,0,3, i td. Na taj nacin u svakom trenutku
      znamo koja linija najduze nije koriscena (to je ona koja je
      poslednja u poretku). Nedostatak ove politike je ocigledan: n!
      vrlo brzo raste i broj stanja postaje preveliki. U slucaju
      asocijativnog mapiranja n ce biti ukupan broj linija u kesu, pa
      je implementacija ove politike prakticno nemoguca. U slucaju
      set-asocijativnog mapiranja ona je upotrebljiva za male velicine
      skupova. Na primer, u slucaju 2-asocijativnog mapiranja, imamo 2
      linije u svakom skupu (tj. dva kandidata za zamenu), i dva
      moguca poretka 0,1 i 1,0. Ova dva stanja se mogu kodirati jednim
      bitom. U slucaju 4-asocijativnog mapiranja imamo 24 moguca
      stanja, pa je za cuvanje stanja potrebno 5 bitova (po svakom
      skupu u kesu). Za 8-asocijativno mapiranje imamo 8! = 40320
      mogucih poredaka, pa je za kodiranje stanja potrebno 16 bitova.
      Naravno, treba uzeti u obzir i slozenost kombinatorne logike
      kojom se obezbedjuju odgovarajuci prelasci iz stanja u stanje.

   -) Pseudo-LRU: Ovo je aproksimacija gornje politike koja je nesto
      manje precizna, ali se znatno jednostavnije implementira.
      Pretpostavimo da imamo n linija kesa koje su kandidati za
      zamenu. Najpre ovaj skup podelimo na dve jednake polovine od po
      n/2 linija kesa. Jednim bitom odredjujemo u kojoj se od te dve
      polovine nalazi kes linija kojoj je najskorije
      pristupano. Ukoliko je ovaj bit 0, znaci da se ova linija nalazi
      u donjoj, a ukoliko je 1 u gornjoj polovini. Na slican nacin se
      sada deli svaka od ovih polovina, pri cemu pri svakoj podeli
      imamo po jedan bit koji nam govori gde se nalazi linija kojoj je
      najskorije pristupano. Prilikom pristupa nekoj kes liniji
      krecemo se kroz ovu hijerarhiju i azuriramo sve bitove na putu
      do te linije.  Prilikom zamene, prati se put ka onim polovinama
      gde se ne nalazi najskorije koriscena linija. Ukupan broj bitova
      po skupu od n kandidata bice n-1. Npr. za 4-asocijativno
      mapiranje imacemo 3 bita po skupu, a za 8-asocijativno mapiranje
      imacemo 7 bitova po skupu. Ova politika se jednostavnije
      implementira, ali je manje precizna. Npr. u slucaju
      4-asocijativnog mapiranja moze se dogoditi da ne odaberemo
      najduze nekoriscenu liniju, vec prvu sledecu u tom smislu.

   -) FIFO (first-in-first-out): Ova strategija pretpostavlja da se
      one linije koje su u kesu najduze najmanje i koriste, dok se one
      koje su u kes stigle kasnije vise koriste (ili ce se vise
      koristiti u buducnosti). Relativno se jednostavno implementira,
      cak i za velike skupove (ili potpuno asocijativno mapiranje).
      Dovoljno je cuvati jedan kruzni brojac koji oznacava redni broj
      linije u kesu u koja je sledeci kandidat za ucitavanje novog
      kes-bloka. Njegova inicijalna vrednost je 0, tako da se u
      pocetku linije kesa popunjavaju redom. Kada se kes prepuni,
      kruzni brojac se vraca na 0, tako da se sledeci kes blok upisuje
      u 0-tu liniju, umesto najstarijeg bloka u kesu. Sledeca se
      zamenjuje linija 1, pa linija 2, i td.

   -) LFU (least frequently used): najredje koriscena linija se
      izbacuje iz kesa. Za ovu strategiju potrebno je da postoji
      brojac uz svaku liniju kesa koji se uvecava pri svakom pristupu,
      kao i slozena logika za uporedjivanje i odredjivanje najmanjeg
      od brojaca. Relativno retko se primenjuje, zbog slozenosti
      implementacije.
      

*) RAZDVOJENI I UNIFIKOVANI KES

   -) Kod razdvojenog kesa postoji poseban kes za podatke, a poseban
      za instrukcije. Kes za instrukcije se popunjava prilikom
      dohvatanja instrukcije, dok se kes za podatke popunjava prilikom
      dohvatanja podataka.
      
   -) Kod unifikovanog kesa u isti kes se smestaju i podaci i
      instrukcije.

   -) Prednost radvojenog kesa je to sto se omogucava prilagodjavanje
      razlicitim obrascima pristupa kod instrukcija i podataka, jer se
      principi lokalnosti kod instrukcija i kod podataka mogu
      koristiti na razlicite nacine. Takodje, instrukcije se samo
      citaju, pa samim tim implementacija moze biti jednostavnija
      (nema politika pisanja, prljavog bita i td.). Najzad, sprecavaju
      se problemi koji se mogu desiti kada neka instrukcija prilikom
      ucitavanja u kes iz njega izbaci podatak samo zato sto su im
      adrese (inace veoma udaljene) takve da se smestaju u isti skup
      kes linija. Nedostatak razdvojenog kesa je u tome sto ne postoji
      fleksibilnost koriscenja prostora u kesu: npr. ako imamo
      relativno mali program koji sadrzi mali broj instrukcija koje se
      ponavljaju u petlji, dobar deo instrukcijskog kesa ce biti
      prazan, a sa druge strane, kes za podatke moze biti prepunjen.
      Zbog toga se razdvojeni kes koristi za male kes memorije, dok se
      vece kes memorije uglavnom izradjuju kao unifikovani kes, zbog
      efikasnijeg iskoriscenja prostora.

*) NIVOI KESA

   -) S obzirom na rastucu razliku u brzini izmedju memorije i
      procesora, obicno se kes memorija organizuje hijerarhijski, u
      vise nivoa. Svaki sledeci nivo je sve veci, ali je i sve
      sporiji.  Na taj nacin se najcesce korisceni podaci nalaze
      u najblizem kesu, oni malo redje korisceni u sledecem, nesto
      sporijem kesu, i td.

   -) Organizacija kesa u vise nivoa moze biti inkluzivna i
      ekskluzivna. U slucaju inkluzivne organizacije, svaki sledeci
      nivo kesa sadrzi sve podatke koje je sadrzao i prethodni, ali i
      dodatne podatke koji u prethodnom nisu postojali. Kod
      ekskluzivne organizacije kes na sledecem nivou ne sadrzi podatke
      sa prethodnog nivoa, vec iskljucivo druge podatke. Prednost
      inkluzivnog pristupa je u tome sto vece kes memorije mogu imati
      vece linije, dok kod ekskluzivnog kesa sve kes memorije u
      hijerarhiji moraju imati kes linije iste velicine. Takodje,
      implementacija inkluzivnog kesa je nesto jednostavnija. Sa druge
      strane, prednost ekskluzivnog kesa je u tome sto efikasnije
      koristi prostor (nema dupliranja podataka u hijerarhiji kesa).

   -) Prilikom citanja, najpre se podatak trazi u najblizem kesu.
      Ukoliko ga pronadjemo, dostavljamo ga procesoru. U suprotnom,
      trazimo ga u sledecem kesu. Ako ga tamo pronadjemo, prebacujemo
      ga u blizi kes i dostavljamo procesoru. U slucaju da je kes
      ekskluzivni, tada se odgovarajuci kes blok nakon prebacivanja u
      blizi kes brise iz onog udaljenijeg, dok u slucaju inkluzivnog
      ne. Ukoliko se ni u drugom kesu ne pronadje podatak, trazi se
      u trecem. Ukoliko ga tamo pronadjemo, prepisujemo ga u prva
      dva kesa i dostavljamo procesoru, i td.

   -) Prilikom pisanja, u slucaju Write-Back politike, podatak se
      azurira u prvom kesu u kome je pronadjen. Prilikom zamene u
      tom kesu, vrsi se eventualno azuriranje na sledecem nivou
      kesa. U slucaju Write-Trough politike uvek se vrsi upis u
      sve nivoe kesa, kao i u glavnu memoriju. 

      U modernim arhitekturama, imamo sledece nivoe kesa:

   -) L1 kes: ovaj kes se nalazi na samom cipu procesora, najblize
      samom procesoru. Realizuje se kao razdvojeni kes. Tipicna
      velicina mu je 32K + 32K. Tipicno se realizuje kao
      8-asocijativni kes.

   -) L2 kes: u pitanju je unifikovani kes. Danas se uglavnom nalazi
      na cipu procesora, i velicina mu je tipicno oko 256K. Tipicno
      se realizuje kao 4-asocijativni kes. 

   -) L3 kes: ovaj kes je obicno znatno veci i zajednicki je za sva
      jezgra na istom procesoru. Velicina mu je obicno 2M do 4M.
      Realizuje se kao 8-asocijativni ili 16-asocijativni kes. 

*) ODLUKE PRI DIZAJNU KESA:

   Prilikom dizajna kesa moramo da donesemo odluke vezane za parametre
   kao sto su velicina kesa, velicina linije kesa, kao i izbor
   asocijativnosti. Evo kako ovi parametri uticu na performanse:

   -) Velicina kesa: ispostavi se da povecavanjem kesa do neke granice
      imamo poboljsanje performansi, ali se u nekom trenutku taj rast
      performansi usporava i postaje beznacajan. Ovo se moze objasniti
      time da sa odredjenom velicinom kesa procenat pogotka postane
      blizak 100% i dalje povecanje kesa nece nista znacajno doprineti
      ubrzanju rada celog sistema (a moze ga usporiti, jer je veci kes
      po prirodni stvari sporiji).

   -) Velicina linije kesa: povecanjem velicine linije kesa do neke
      mere se poboljsavaju performanse, ali se u nekom trenutku te
      performanse pocinju kvariti. Ovo se moze objasniti na sledeci
      nacin: za premale linije kesa slabo se koristi princip prostorne
      lokalnosti, dok se za prevelike linije kesa smanjuje preciznost
      (ucitavamo gomilu podataka koji nam verovatno nece trebati).
      Velicina od 32 bajta koju koriste Intel-ovi procesori je zato
      neka optimalna velicina.

   -) Asocijativnost: povecavanjem stepena asocijativnosti se povecava
      procenat pogodaka kesa. Potpuno asocijativni kes je u tom smislu
      najbolji, ali je njegova implementacija previse slozena, pa se
      otuda dizajneri obicno odlucuju za set-asocijativno mapiranje.
      Pritom, veci skupovi predstavljaju bolje resenje i primenjuju se
      kada god to uslovi dozvoljavaju (pre svega cena implementacije).

*) KOHERENTNOST KESA

   -) U slucaju da vise uredjaja pristupaju podacima u memoriji
      (npr. vise procesora, procesor i DMA kontroler, i sl.), moze
      nastati problem ako procesor promeni neki podatak, ali se ta
      promena sacuva samo u njegovom privatnom kesu, ali ne i u
      memoriji.
      
   -) Svojstvo da se sve promene upisane u memoriju od strane jednog
      procesora vide od strane ostalih procesora naziva se
      KOHERENTNOST KESA.

   -) Moderni procesorski sistemi sa vise nivoa kesa od kojih su neki
      privatni za pojedinacne procesore (tj. jezgra) zahtevaju veoma
      slozenu logiku za implementaciju koherentnosti kesa.

   -) Uobicajene politike koherentnosti su: INVALIDACIJA PRI UPISU
      (WRITE INVALIDATE), i AZURIRANJE PRI UPISU (WRITE UPDATE). U
      prvom slucaju kontroler kesa svakog procesora osluskuje promene
      u kesevima drugih procesora. Cim se neka linija koja sadrzi neki
      kes-blok promeni, tada se kopija tog kes-bloka u kesu naseg
      procesora invalidira (tj. validni bit se postavi na 0). U
      drugoj strategiji se vrsi azuriranje linije kesa na osnovu
      promenjene linije u kesu drugog procesora. 

      Obe ove politike su upotrebljive samo u slucaju WRITE-THROUGH
      politike pisanja kesa. U slucaju WRITE-BACK politike, kopija
      u memoriji ne mora biti azurna, pa se situacija dodatno
      komplikuje. U tom slucaju se obicno koriste slozenije politike,
      medju kojima je jedna od najcescih tzv. MESI politika
      (Modified-Exlusive-Shared-Invalid). Za vise informacija,
      konsultovati dodatnu literaturu.
