În urma realizării acestei teme:
Instructiunile si datele programelor sunt stocate in RAM. Aceasta este o memorie rapida, dar mult mai inceata fata de viteza cu care prelucreaza datele procesoarele. Astfel, pentru a reduce mult din timp a fost introdusa memoria cache, o memorie specifica procesorului, de mici dimensiuni, foarte rapida(intermediara intre viteza procesorului si a RAM-ului). Cele mai des utilizate date sunt stocate in cache, pentru a fi accesate mult mai rapid. ( why computers need cache).
In cache se incarca datele accesate de nucleu, pentru a putea fi accesate mai rapid data viitoare cand va fi nevoie.
Fie un procesor cu 2 nuclee si 2 nivele de cache (un L1 privat fiecarui nucleu si un L2 comun). Pentru fiecare acces la memorie, se face in prealabil o cautare a acelei adrese in memoria cache (intai in L1 si apoi L2). Daca adresa nu este gasita nicaieri, se va cauta in RAM si se va copia in L2 si in L1 al respectivului nucleu care a facut accesul. Daca adresa este insa gasita in L1, sa va folosi, iar daca e in L2, se va copia inainte in L1 si apoi se va folosi. Astfel se micsoreaza timpul de acces pentru valorile de la adresele care au mai fost accesate anterior.
Asa arata memoria procesorului din exemplu:
Sa luam un exemplu pentru simplificarea explicatiei. Fie un procesor cu 2 nuclee. Fiecare nucleu are o memorie cache privata L1, iar ambii au acces la o memorie shared L2. In L1 pentru fiecare nucleu sunt adresele si datele pe care repectivul nucleu le-a accesat, pe cand in L2 sunt o reuniune de adrese si date accesate de ambii.
Astfel, sa presupunem ca memoria RAM arata ceva de genul acesta (prima coloana e adresa, a doua e valoarea de la acea adresa):
20000 7 20004 10 20008 0
Un nucleu o sa vrea sa citeasca valoarea de la adresa 20000. Presupunand ca nu exista altceva in cache pana acum, ca sa simplificam exemplul, el va ajunge cu cautarea adresei pana in RAM (nu a gasit-o nici in L1, nici in L2). O gaseste in RAM, o copiaza in L2 si in cache-ul L1 al lui. Al doilea nucleu citeste si el valoarea de la adresa 20000, pe care o gaseste deja in L2. O copiaza in cache-ul L1 al lui.
Apoi, sa spunem ca nucleul 1 vrea sa modifice valoarea de la adresa 20000. O cauta in L1, o gaseste, o modifica in L1, apoi o modifica si in L2. Daca acum nucleul 2 vrea sa citeasca valoarea de la adresa 20000, va citi o valoare veche (asta are el in L1), insa vrem sa citeasca valoarea noua. Pentru aceasta, exista notiunea de dirty bit, care este setat atunci cand o intrare din cache nu are cea mai recenta valoare. Astfel, cand nucleul 1 modifica valoarea de la adresa 20000, o modifica in L1, in L2 si o pune pe dirty pe cea din L1 al celuilalt nucleu. Astfel, cand acela va vrea sa citeasca data de la adresa 20000, o va cauta in L1, vede ca e dirty, astfel ca merge la nivelul 2, in L2, unde gaseste valoarea updatata, pe care o copiaza la el in L1 si apoi o foloseste.
Modalitatea de mapare a unei memorii cache reprezinta felul in care datele sunt organizate in interiorul memoriei pentru a facilita accesarea rapida. Fara sa intram in prea multe detalii, vom prezenta doar un tip de mapare, care va fi si de folos in rezolvarea temei.
Memoria cache are o dimensiune, sa spunem cacheDim bytes. Ea este formata din blocuri de cache. Vom presupune ca un bloc de cache are dimensiunea blockDim bytes, rezulta ca sunt nrBlocks = cacheDim / blockDim blocuri in acest cache. La o mapare set asociativa pe 2 cai, fiecare 2 blocuri reprezinta cai intr-un set, astfel ca sunt nrSets = nrBlocks / 2 seturi. O reprezentare vizuala a acestei mapari poate fi vazuta mai jos:
Indexarea in acest cache se face cu ajutorul indexului setului (de la 0 la nrSets - 1). Astfel, se folosesc anumiti biti (dupa cum vom vedea) din adresa pentru a extrage numarul setului din cache pentru aceasta.
In acest fel, daca se doreste cautarea unei anumite adrese in cache, se va afla numarul setului in care aceasta poate fi si apoi se va cauta in interiorul setului, daca adresa cautata se afla printre cele doua valori posibile.
Pentru adaugarea unei valori noi in cache, avem nevoie de urmatoarea notiune:
Cand vrem sa adaugam o noua valoare in cache, si am identificat setul in care trebuie sa o adaugam, avem urmatoarele cazuri:
Astfel, Least Recently Added spune ca:
Pana acum am vazut cum interactioneaza procesorul cu datele citite din RAM si adaugate in cache. Apoi, am vazut cum interactioneaza cu datele care sunt deja in cache.
Datele din cache trebuie sa ajunga si inapoi in RAM, la un moment dat. Acest moment este dat de politica de scriere in RAM. Vom vorbi doar despre o politica, de interes pentru aceasta tema, Write-back.
Aceasta politica spune ca o valoare este scrisa in RAM atunci cand este scoasa din cache prin adaugarea unei alte intrari.
Ne propunem sa simulam functionalitatea memoriei cache pentru un procesor folosind hashtable-uri. Vom considera un procesor cu doua nuclee, astfel incat:
Memoriile cache vor folosi maparea set asociativa pe 2 cai si o politica de write-back pentru scrierea in RAM, ambele prezentate anterior.
Ele vor avea urmatoarea dimensiune:
Memoriile cache trebuie implementate ca hashtable-uri generice in care:
Indexul setului din cadrul cache-ului va fi calculat cu ajutorul:
Pentru operatia read:
Pentru operatia write:
Veti avea 2 fisiere de intrare:
Fisierul ram.in are urmatoarea structura:
address value
Fisierul operations.in are urmatoarea structura:
coreNumber operation address [newData]
Veti avea 2 fisiere de iesire:
Fisierul cache.out trebuie sa aiba urmatoarea structura:
unde liniile sunt de forma:
setIndex wayIndex address value [*]
Fisierul ram.out trebuie sa pastreze structura fisierului ram.in.
Aveți la dispoziție o arhivă ce conține o suită de teste publice (singurele cu care va fi testată tema) și un script de testare automată a temei. Scriptul este de bash (Linux).
Atenție! Pentru ca testarea sa mearga, executabilul generat de tema voastră trebuie să fie în același director cu scriptul test.sh, respectiv cu directoarele de test (cele numerotate de la 1 la 10) din arhiva de mai jos.
Temele vor trebui trimise pe vmchecker. Atenție! Temele trebuie trimise în secțiunea Structuri de Date (CA).
Arhiva trebuie să conțină:
De aceea, vă sfătuim să nu vă lăsați rezolvări ale temelor pe calculatoare partajate (la laborator etc), pe mail/liste de discuții/grupuri etc.
Q: Se poate folosi STL?
A: Nu puteți folosi structurile gata implementate în STL. Obiectivul principal al cursului de structuri de date este acela ca voi să implementați structurile respective.