Sunteți pe pagina 1din 59

ARHITECTURA SISTEMELOR DE CALCUL

1. DEZVOLTĂRI ARHITECTURALE ÎN DOMENIUL SISTEMELOR DE CALCUL

Cea mai importantă categorie de dezvoltări arhitecturale vizează aplicarea


paralelismului care presupune execuŃia simultană a mai multor operaŃii. A 2-a categorie
semnificativă de dezvoltări arhitecturale vizează satisfacerea unor cerinŃe ale software-ului
(preluarea la nivel hardware a unor funcŃii specifice sistemului de operare). Toate aceste
dezvoltări au ca scop final creşterea vitezei de procesare a sistemului de calcul. Cele mai
importante dezvoltări arhitecturale pot fi grupate pe baza zonelor vizate:

1. cele care vizează proiectarea internă a procesorului


2. cele care vizează interfaŃa procesor - memorie
3. cele care vizează sistemul de ierarhizare a memoriei
4. cele care vizează utilizarea sistemelor multiprocesor

1.1. Proiectarea procesoarelor pipeline

Tehnica pipeline aplicată în toate sistemele performante vizează îmbunătăŃirea


performanŃelor procesorului. Activitatea procesorului se concentrează asupra a două
operaŃii (faze) majore:

1. fetch-ul instrucŃiunii (extragerea codului instrucŃiunii din memorie )


2. execuŃia instrucŃiunii extrase.

În prima fază, o instrucŃiune este citită din memorie utilizând registrul program counter ca
pointer pentru locaŃia de memorie. În ultima parte a ciclului fetch instrucŃiunea este
decodificată. După decodificare se trece la ciclul (faza) de execuŃie a instrucŃiunii. În prima
parte a execuŃiei vor fi obŃinuŃi operanzii din registre UC sau din memorie şi apoi operaŃia
specificată se aplică acestor operanzi. Rezultatele sunt depuse în registre UC sau în locaŃii
de memorie, la finele ciclului de execuŃie.
ExecuŃia unei instrucŃiuni şi fetch-ul instrucŃiunii următoare pot fi executate
simultan în anumite condiŃii. Prima condiŃie necesară pentru suprapunerea cu succes a
ciclurilor fetch şi respectiv execuŃie este aceea că instrucŃiunea ce va fi extrasă din memorie
(faza fetch) trebuie identificată înaintea execuŃiei instrucŃiunii anterioare. Această condiŃie
este îndeplinită în cazul instrucŃiunilor executate secvenŃial. Există însă instrucŃiuni care
perturbă caracterul secvenŃial al execuŃiei cum ar fi, de exemplu, instrucŃiunile de salt. În
aceste cazuri instrucŃiunea ce va fi extrasă din memorie va fi identificată doar după execuŃia
completă a instrucŃiunii de salt (calculul adresei de salt). În consecinŃă, execuŃia unei
instrucŃiuni de salt nu poate fi suprapusă cu fetch-ul instrucŃiunii următoare.

1
Dezvoltări arhitecturale în domeniul sistemelor de calcul

Cele două cicluri de bază, fetch şi execuŃie, pot fi divizate mai fin în trei cicluri
care, în anumite condiŃii, pot fi suprapuse:

1. fetch instrucŃiune
2. decodificare instrucŃiune şi fetch operanzi
3. execuŃie

ExecuŃia, la rândul ei, poate fi divizată într-un număr de suboperaŃii dependente de tipul
instrucŃiunii. OperaŃiile aritmetice cu numere întregi sunt relativ simple şi pot fi
implementate într-un singur pas (modul) în timp ce operaŃiile mai complexe, cum ar fi
înmulŃirea sau împărŃirea în virgulă flotantă, pot necesita câŃiva paşi succesivi care vor fi
executaŃi într-o cascadă de module.
În procesoarele performante cele 3 operaŃii de bază ce compun ciclul instrucŃiunii
(fetch instrucŃiune, decodificare instrucŃiune şi fetch operanzi, execuŃie instrucŃiune) sunt
implementate într-o structură pipeline.
Structura pipeline (fig. 1.1.) este formată dintr-un număr de module conectate în
cascadă. Fiecare modul execută una din operaŃiile de bază evidenŃiate.

Fig. 1.1. Structura pipeline

Ieşirea unui modul este aplicată ca intrare în modulul următor. InformaŃia care va
declanşa cascada de operaŃii în structura pipeline va fi aplicată pe intrarea primului modul
iar rezultatele sunt produse de către modulul final (uneori de module intermediare).
Modulele intermediare produc rezultate parŃiale.
Timpul consumat pentru procesarea unei instrucŃiuni în cascada pipeline va fi cel
puŃin tot atât de mare cu cel consumat pentru execuŃia aceleiaşi instrucŃiuni într-un procesor
convenŃional format dintr-o singură unitate funcŃională complexă şi omogenă. Totuşi,
procesorul pipeline poate fi substanŃial mai rapid comparativ cu procesorul convenŃional
omogen. Deşi rezultatele sunt întârziate cu timpul total de procesare (obŃinut prin
cumularea timpilor de procesare aferenŃi tuturor modulelor pipe), totuşi, aceste rezultate
sunt livrate la rata la care procesorul pipeline este alimentat cu instrucŃiuni. Rata de
alimentare va fi egală cu timpul de procesare aferent celui mai lent modul din structura pipe.
Pentru instrucŃiuni secvenŃiale procesorul pipeline va fi substanŃial mai rapid decât
procesorul clasic omogen.

2
ARHITECTURA SISTEMELOR DE CALCUL

În mod cert, procesarea diverselor instrucŃiuni nu este întotdeauna similară


(comparativ cu instrucŃiunile simple, instrucŃiunile complexe prezintă faze de execuŃie
complexe, eventual divizate şi repartizate pe o cascadă de module de execuŃie) şi nici
întotdeauna secvenŃială şi predictibilă (instrucŃiunile de salt perturbă firul procesării
secvenŃiale şi predictibile a instrucŃiunilor). Proiectantul trebuie să acorde o atenŃie
deosebită problemelor nesimilarităŃii şi non-secvenŃialităŃii. O serie de alte complicaŃii apar
la proiectare datorită interdependenŃelor dintre instrucŃiuni (de regulă, rezultatul obŃinut pe
o instrucŃiune va fi preluat ca operand de una din instrucŃiunile următoare). Totuşi,
performanŃe substanŃial îmbunătăŃite pot fi obŃinute prin utilizarea tehnicii pipeline şi virtual
toate sistemele şi microprocesoarele moderne au o structură pipeline.

1.2. InterfaŃa procesor - memorie

InterfaŃa procesor - memorie rezolvă:

1. transferul instrucŃiunilor din memorie spre procesor în ciclul fetch instrucŃiune.


2. transferul datelor între procesor şi memorie în faza de execuŃie a instrucŃiunii.

Este important ca transferul instrucŃiunilor/datelor să se facă la rata maximă de transfer


suportată de către destinaŃie (procesor sau memorie). Sunt inutile încercările de a depăşi
această limită. La proiectarea sistemelor sunt luate în considerare soluŃii care vizează
egalizarea ratelor de transfer suportate de către procesor şi respectiv memorie. Dacă ratele
maxime de transfer aferente procesorului şi respectiv memoriei sunt diferite, atunci, viteza
globală a sistemului este afectată de către dispozitivul mai lent. În mod normal procesorul
poate opera la o viteză superioară celei aferente memoriei principale.

A. Creşterea lărgimii benzii de comunicaŃie

Lărgimea de bandă a unui canal de comunicaŃie (bandwidth) este dată de


cantitatea de informaŃie care poate fi transferată de-a lungul canalului în unitatea de timp şi
se măsoară în biŃi/secundă. Lărgimea benzii poate creşte prin simpla creştere a numărului de
linii sau fire din canalul de comunicaŃie. Creşterea, de exemplu, a numărului de linii de date
de la 32 la 64 va conduce la dublarea lărgimii de bandă. Reducerea latenŃei (latency) devine
tot mai dificilă deoarece viteza semnalelor electrice este tot mai greu de schimbat (limitări
tehnologice). LatenŃa reprezintă timpul necesar pentru transferul unui bit.
O tehnică general aplicată pentru creşterea ratei efective aferente unei unităŃi lente
constă în multiplicarea unităŃii respective şi execuŃia simultană a mai multor transferuri. De
exemplu, dacă destinaŃia poate accepta informaŃii la o rată de opt ori mai mare decât rata de
generare a informaŃiilor la sursă, atunci sursa poate fi multiplicată de opt ori şi în consecinŃă
opt transferuri simultane pot fi executate către destinaŃie.

3
Dezvoltări arhitecturale în domeniul sistemelor de calcul

Tehnica poate fi aplicată pentru a egaliza viteza de transfer a memoriei cu cea a


procesorului, prin multiplicarea modulelor de memorie. Să presupunem, spre exemplificare,
că o singură instrucŃiune este extrasă din memorie într-un ciclu fetch. Dacă memoria se
organizează în două module cu busuri de date separate spre procesor, două instrucŃiuni vor
putea fi extrase din memorie simultan, crescând rata de transfer de două ori.
Dacă rata de transfer trebuie să crească de n ori în scopul egalizării ratei maxime
de transfer suportată de procesor, atunci, vor fi prevăzute n module de memorie. De regulă
n este o putere a lui 2. Pentru a obŃine blocuri de locaŃii adresate secvenŃial, cea mai
semnificativă parte a adresei va specifica adresa blocului de n locaŃii şi cea mai puŃin
semnificativă parte a adresei va specifica cuvântul sau locaŃia din cadrul blocului. Utilizând
module multiple de memorie în acest mod apar constrângeri în ceea ce priveşte blocurile
transferate. Această organizare devine eficientă numai dacă toate (sau aproape toate)
cuvintele ce compun un bloc transferat sunt şi necesare în procesor; în esenŃă am obŃinut o
extindere a lungimii cuvântului de memorie (de n ori).
Este posibil să se emită şi adrese diferite spre cele n module astfel încât n cuvinte
de la adrese diferite şi din module diferite, vor putea fi accesate simultan. Această
organizare se mai numeşte memorie cu adresare întreŃesută (interleaving). Este important să
discernem între extensia lungimii cuvântului de memorie şi adevărata memorie cu adresare
întreŃesută. În prima organizare, blocuri de locaŃii consecutive pot fi accesate simultan; în a
doua, locaŃii neconsecutive pot fi accesate simultan, dacă aceste locaŃii se găsesc în module
diferite. În cazul adresării întreŃesute, adresa de memorie se împarte în două câmpuri, unul
care selectează modulul şi celălalt care selectează locaŃia din cadrul modulului. În funcŃie de
poziŃia relativă a celor două câmpuri, apar două variante de întreŃesere:

- întreŃesere de ordin inferior (low order interleaving)


- întreŃesere de ordin superior (high order interleaving)

Cele două formate alternative de adresare sunt evidenŃiate în figura 1.2.

Cel mai Cel mai puŃin


semnificativ semnificativ
bit bit
Adresa locaŃiei în cadrul modulului Adresă modul

a) ÎntreŃesere de ordin inferior

Adresă modul Adresa locaŃiei în cadrul modulului

b) ÎntreŃesere de ordin superior

Fig. 1.2. Formate de adresare pentru întreŃesere

4
ARHITECTURA SISTEMELOR DE CALCUL

ÎntreŃeserea de ordin inferior este indicată pentru sistemele monoprocesor deoarece


locaŃii consecutive de memorie sunt locate în module diferite de memorie şi pot fi accesate
simultan. Cu patru module şi întreŃesere de ordin inferior, de exemplu, adresele primului
modul vor fi 0, 4, 8, 12, 16, ..., adresele celui de-al doilea vor fi 1, 5, 9, 13, 17, ..., ale celui
de-al treilea vor fi 2, 6, 10, 14, 18, ..., şi ale celui de-al patrulea vor fi 3, 7, 11, 15, 19, ... .
În figura 1.3. se prezintă organizarea unei memorii cu adresare întreŃesută pentru
un sistem monoprocesor. În structură apar busuri de date separate care conectează
procesorul la fiecare modul de memorie.
Câmpul de adresă modul selectează modulele, iar adresa locaŃiei din cadrul
modulului este încărcată succesiv în registrele de adresă. De îndată ce adresa este încărcată,
fiecare modul va parcurge etapa de selecŃie a locaŃiei ce urmează a fi accesată. La citire,
datele apar succesiv pe fiecare bus, după consumarea timpului de acces la memorie. La
scriere, datele sunt generate succesiv de către procesor pe busul de date aferent fiecărui
modul.

Fig. 1.3. Memorie întreŃesută cu bus de date extins

Aşa cum se indică în figura 1.4., este posibilă organizarea şi cu un singur bus de
date. Fiecare modul va fi prevăzut cu un registru buffer de date bidirecŃional care va reŃine
datele de scris în modul sau respectiv datele citite din modul.

5
Dezvoltări arhitecturale în domeniul sistemelor de calcul

Fig. 1.4. Memorie întreŃesută cu un singur bus de date

Activitatea în timp a unui astfel de sistem este prezentată în figura 1.5.

Fig. 1.5. ÎntreŃesere cu adrese diferite pentru fiecare modul de memorie

6
ARHITECTURA SISTEMELOR DE CALCUL

Este posibilă aplicarea aceleiaşi adrese tuturor modulelor de memorie astfel încât
vor fi accesate cuvinte consecutive în memorie (în cazul întreŃeserii de ordin inferior).
Activitatea în timp a unui astfel de sistem este prezentată în figura 1.6.
Memoria cu adresare întreŃesută poate fi utilizată în sistemele pipeline pentru a
extrage simultan mai multe instrucŃiuni din memorie. După extragere, aceste instrucŃiuni vor
fi executate secvenŃial în tehnică pipeline. Prin această adresare întreŃesută interfaŃa
procesor-memorie este eliberată pentru accesarea operanzilor.

Fig. 1.6. ÎntreŃesere cu aceeaşi adresă pentru toate modulele de memorie

B. Buffer-e de prefetch

Dacă lărgimea benzii de comunicaŃie cu memoria creşte suficient, poate să apară


situaŃia în care procesorul nu mai face faŃă tuturor instrucŃiunilor şi respectiv datelor extrase
din memorie. InstrucŃiunile şi datele pot fi extrase anticipat, înainte de a fi necesare, şi
stocate într-un buffer de prefetch de tip FIFO (First-In First-Out). În mod curent,
instrucŃiunile extrase anticipat sunt consecutive în program. Buffer-ul de prefetch
contracarează efectul negativ pe care l-ar putea avea timpul variabil de execuŃie al
diferitelor instrucŃiuni (de complexităŃi diferite) precum şi efectul utilizării memoriei de
către alte dispozitive (alte procesoare sau periferice cu acces DMA). Microprocesoarele
conŃin frecvent astfel de buffere de prefetch în care se stochează instrucŃiunile înainte de a fi
executate. De exemplu, Intel 486 conŃine un buffer de prefetch de 32 octeŃi. În acest caz
particular, buffer-ul de prefetch permite şi asamblarea instrucŃiunilor de lungime variabilă
înainte de lansarea lor în execuŃie.

7
Dezvoltări arhitecturale în domeniul sistemelor de calcul

C. Memorii cache

O creştere semnificativă a performanŃelor unui sistem se poate obŃine dacă, între


procesor şi memoria principală, se introduce o memorie de mare viteză numită memorie
cache, ca în figura 1.7.

Fig. 1.7. Memoria cache

InstrucŃiunile programului şi datele sunt mai întâi încărcate în cache din memoria
principală şi apoi accesate rapid în cache de către procesor. Presupunând că informaŃiile vor
fi accesate mai mult decât o singură dată, lucru de regulă valabil pentru instrucŃiunile din
cadrul buclelor de program, se pot obŃine creşteri substanŃiale în ceea ce priveşte viteza de
operare a sistemului. Cele mai multe sisteme cu microprocesoare au memorii cache interne
(on-chip) şi/sau externe microprocesorului. Există sisteme cu cache-uri separate, pentru
instrucŃiuni şi respectiv date, sau cu cache-uri unificate, care găzduiesc atât instrucŃiuni cât
şi date. IniŃial, memoriile cache erau mici. Motorola MC 68040 are cache-uri separate
pentru instrucŃiuni (4 KByte) şi respectiv date (4 KByte). Intel 486 are un cache unificat de 8
KByte în timp ce Pentium are din nou cache-uri separate, fiecare de 8 KByte. TendinŃa
actuală este de a implementa cache-uri separate tot mai mari, şi chiar de a implementa
cache-uri pe două nivele (un prim nivel de capacitate relativ redusă dar de viteză extrem de
mare în interiorul microprocesorului şi un al doilea nivel de capacitate mai mare dar şi de
viteză mai mică în exteriorul acestuia). Totuşi, cache-ul (chiar de pe nivelul 2) trebuie să
opereze mai rapid decât memoria principală, altfel implementarea sa nu mai are sens.

1.3. Memoria externă şi ierarhizarea memoriei

Memoria externă este constituită din echipamente periferice care utilizează


tehnologia magnetică pentru înregistrarea informaŃiei. Cel mai comun este discul magnetic
la care informaŃia este înregistrată pe piste concentrice pe o suprafaŃă magnetică a unui disc
care se roteşte. Discurile magnetice sunt cu câteva ordine de mărime mai lente decât
memoria principală. Dacă memoria principală are un timp de acces de ordinul 20 - 100 ns,
timpul de acces la disc este de 5 - 20 ms şi este dificilă îmbunătăŃirea substanŃială a acestui
timp datorită naturii mecanice a acestui periferic. A existat totuşi, de-a lungul anilor, o
creştere graduală a performanŃelor discurilor magnetice. Se poate utiliza aceiaşi tehnică
pentru creşterea lărgimii benzii de comunicaŃie (bandwidth) cu discul. Un fişier care trebuie
memorat va fi împărŃit în blocuri şi blocurile consecutive sunt memorate şi accesate

8
ARHITECTURA SISTEMELOR DE CALCUL

întreŃesut (interleaved) pe unităŃi de disc diferite, ca în figura 1.8. Tehnica descrisă este
cunoscută ca “file striping”. Dimensiunea blocului poate fi de un octet, caz în care unităŃile
de disc vor trebui probabil sincronizate, sau de mai mulŃi octeŃi. Cu n unităŃi de disc
lărgimea benzii de comunicaŃie va creşte de n ori.

Fig. 1.8. Discuri multiple cu accesare întreŃesută

Mai multe unităŃi de disc de capacitate mică pot înlocui o unitate de capacitate
mare şi în scopul creşterii toleranŃei la defect. În cazul defectării unei unităŃi sistemul va fi
reconfigurat, unitatea defectă izolată şi eliminată din configuraŃie, şi sistemul va utiliza în
continuare doar restul unităŃilor de disc. Termenul RAID (Redundant Array of Inexpensive
Disks) este utilizat pentru a descrie acest tip de organizare. Există o varietate de periferice
magnetice, cum ar fi discurile Winchester, discurile flexibile, benzile magnetice etc.
Discurile optice, cum sunt CD-ROM-urile, oferă o capacitate foarte mare de memorare şi
reprezintă un nou nivel în memoria ierarhizată a sistemului. O mare parte a îmbunătăŃirilor
arhitecturale vizează eficientizarea acestei memorii ierarhizate; ea trebuie să constituie un
suport eficient pentru multiprogramare.
Multiprogramarea este termenul utilizat pentru descrierea sistemului de
programare în care mai multe programe utilizator sunt executate, aparent concurent, prin
execuŃia secvenŃială a câte unei părŃi din fiecare program. În prezenŃa memoriei ierarhizate
este necesar transferul programelor din memoria externă în memoria principală înainte de
lansarea acestora în execuŃie. În mod similar şi datele trebuie transferate. Deoarece memoria
principală are o capacitate limitată, programele şi datele nenecesare la un moment dat vor fi
transferate înapoi pe disc până în momentul în care sunt din nou solicitate. Acest trafic
permanent de programe şi date între memoria principală şi memoria externă necesită un

9
Dezvoltări arhitecturale în domeniul sistemelor de calcul

management de memorie, preferabil “ascuns” utilizatorului şi activat automat la nevoie. Cel


mai important sistem de gestiune a memoriei este cunoscut sub denumirea de memorie
virtuală. Aceasta creează un mecanism automat care asigură încărcarea programelor şi a
datelor din memoria externă în memoria principală (înaintea lansării acestora în execuŃie)
fără ca programatorul să trebuiască să programeze aceste transferuri. InformaŃia memorată
este împărŃită în blocuri de dimensiune fixă, numite de regulă pagini, care sunt vehiculate,
după necesităŃi, între memoria principală şi cea externă. Adresele operanzilor, utilizate în
cadrul programelor, nu sunt alterate, în schimb un mecanism hardware de translatare va
translata aceste adrese (devenite logice) aşa încât ele să refere (fizic) acele locaŃii de
memorie ce compun pagina în care a fost încărcat programul respectiv.

1.4. Sisteme multiprocesor

Sistemele multiprocesor sunt arhitecturi în care mai multe procesoare lucrează


coerent şi concurent pentru execuŃia unui singur task. În cazul în care n procesoare lucrează
simultan şi continuu la rezolvarea aceluiaşi task, ne putem aştepta ca rezultatele să fie
obŃinute de n ori mai rapid decât în cazul în care un sistem uniprocesor rezolvă acelaşi task.
Totuşi, nu întotdeauna este uşor de partiŃionat un task astfel încât cele n procesoare să
lucreze simultan şi continuu, şi chiar în cazul în care este posibilă această partiŃionare, în
versiunea multiprocesor apar comunicaŃiile interprocesor necesare pentru corelarea
funcŃionării celor n procesoare şi care consumă timp suplimentar.
Sistemele multiprocesor se pot obŃine plecând de la sisteme uniprocesor prin
simpla adăugare a unor noi procesoare care vor partaja memoria existentă, rezultând aşa-
numitul sistem multiprocesor cu memorie partajată (shared memory). Fiecare procesor
poate avea şi o memorie locală, dar va utiliza memoria partajată pentru a transfera
informaŃii altor procesoare şi pentru a obŃine programe şi informaŃii partajate. În sistemele
multiprocesor unibus toate procesoarele sunt conectate pe acelaşi bus. Această arhitectură
se pretează doar pentru un număr mic de procesoare, caz în care unibusul ar putea satisface
cerinŃele de comunicaŃie şi de trafic de informaŃie ce se impun.
Într-o altă topologie, sistemele multiprocesor pot utiliza linii de comunicaŃie
directe între procesoare. În acest caz procesoarele operează independent şi îşi transmit
informaŃii printr-un protocol denumit “mesage - passing“ şi nu printr-o memorie partajată.
Totalitatea conexiunilor interprocesor formează o reŃea de interconectare iar arhitectura este
pretabilă pentru tehnologia VLSI cu număr mare de procesoare. Arhitectura “mesage -
passing“ nu suferă de probleme ca:

1. menŃinerea consistenŃei între memoriile locale şi cea partajată


2. controlul sever al acceselor la informaŃii partajate.

10
ARHITECTURA SISTEMELOR DE CALCUL

2. PROIECTAREA SETULUI DE INSTRUCłIUNI

În acest capitol vom proiecta un set de instrucŃiuni reprezentativ pentru multe


sisteme cu set redus de instrucŃiuni (RISC - Reduced Instruction Set Computer). Vom stabili
mnemonicele şi formatele care vor fi utilizate în capitolele următoare.

2.1. Caracteristicile procesorului

Indiferent de tip, toate procesoarele execută două operaŃii de bază: extrag


instrucŃiuni din memorie, şi execută instrucŃiunile extrase. Prima problemă de proiectare
constă în stabilirea setului de instrucŃiuni şi a formatelor de instrucŃiuni pe care procesorul
le va recunoaşte. În ultima perioadă arhitecturile RISC au devenit foarte populare. În
contrast cu procesoarele CISC (Complex Instruction Set Computer), procesoarele RISC
recunosc un set redus de instrucŃiuni simple, cu formate şi moduri de adresare simple. În
consecinŃă, hard-ul procesorului se reduce cantitativ iar proiectarea sa devine mult mai
“curată“ şi atractivă. Majoritatea procesoarelor RISC prezintă seturi şi formate de
instrucŃiuni cu un grad ridicat de similaritate.
Nu există o definiŃie foarte precisă a procesorului RISC, a instrucŃiunii reduse sau
a instrucŃiunii complexe. În general o instrucŃiune complexă este aceea care necesită mulŃi
paşi pentru execuŃie, în timp ce o instrucŃiune redusă poate fi executată în foarte puŃini paşi.
Procesoarele RISC prezintă un număr important de trăsături comune rezultate din principiul
unanim acceptat de către toŃi proiectanŃii de structuri RISC: cel mai simplu este şi cel mai
rapid.

2.1.1. Utilizarea memoriei şi a registrelor

O trăsătură importantă şi comună tuturor procesoarelor RISC, care vizează setul de


instrucŃiuni, este decizia de utilizare a memoriei numai pentru memorarea datelor, şi de a
utiliza registrele CPU (Central Processing Unit) pentru toate operaŃiile aritmetico-logice. În
contrast cu arhitecturile CISC, în cazul RISC nu este posibilă execuŃia operaŃiilor
(instrucŃiunilor) aritmetice asupra unor operanzi locaŃi în memorie. Obiectivul esenŃial în
cazul RISC este acela de a proiecta pentru viteză maximă, evitând utilizarea memoriei ori
de câte ori este posibil, deoarece accesele la memorie sunt mult mai lente comparativ cu
accesele la registre CPU. Pentru flexibilitate maximă, în cazul instrucŃiunilor aritmetice, se
utilizează formatul cu trei adrese (de registru). De regulă în procesor se implementează un
set de 32 registre. Numărul reprezintă un compromis între două cerinŃe:
- un număr cât mai mare de registre reprezintă optimul pentru compilator
- comutarea contextului devine tot mai lentă cu creşterea numărului de registre.

11
Proiectarea setului de instrucŃiuni

De asemenea, pe măsură ce creşte numărul de registre (în termenii puterilor lui 2),
creşte şi timpul de acces la registre şi acest lucru trebuie evitat. Evident că şi memoria
trebuie accesată pentru citirea şi încărcarea în registre a diverşilor operanzi şi pentru
memorarea diverselor rezultate obŃinute în registre. Transferurile cu memoria sunt
gestionate prin instrucŃiuni de tip load şi respectiv store şi acestea sunt principalele
instrucŃiuni care accesează memoria. Formatul load/store este caracteristic procesoarelor
RISC.
Vom nota cele 32 registre R0 - R31. Deşi toate vor fi registre generale, adiŃional
câteva dintre acestea vor avea şi funcŃii speciale. R0 va conŃine permanent constanta 0 şi nu
poate fi utilizat în alt scop. Acesta este un principiu general de proiectare şi este respectat
deoarece este foarte avantajos să avem un registru care conŃine constanta zero pentru
instrucŃiunile de ştergere (iniŃializate cu zero) şi de comparare cu zero. Nu vom prevedea o
instrucŃiune explicită de tip “move” registru - registru. Aceste transferuri vor fi realizate
prin instrucŃiuni ADD (adunare) în care unul dintre operanzi va fi R0 (constanta zero).

2.1.2. Lungimea instrucŃiunilor şi a operanzilor

Începând cu 1990 tehnologiile de fabricaŃie au permis integrarea procesoarelor pe


32 şi chiar 64 biŃi într-un singur circuit VLSI. Evident că în cazul RISC, unde unitatea de
comandă este simplă, proiectantul trebuie să decidă dacă va utiliza aria disponibilizată în
alte scopuri cum ar fi, de exemplu, memorie cache ”on-chip“ de capacitate mai mare. 32
biŃi asigură o precizie rezonabilă pentru operaŃiile cu întregi în timp ce 64 biŃi par rezonabili
pentru operaŃiile în virgulă flotantă. Există deja procesoare care suportă chiar 128 biŃi. De
exemplu, procesorul RISC i860 are instrucŃiuni "load/store" pe 128 biŃi.
DiferenŃe arhitecturale semnificative sunt foarte puŃine între procesoarele pe 32 şi
respectiv 64 de biŃi în ceea ce priveşte unitatea de control; principalele diferenŃe constau în
lungimea diferită a registrelor interne, ALU şi respectiv numărul diferit de linii aferente
busurilor interne şi externe CPU. Odată cu creşterea lungimii cuvântului la 32/64 biŃi a
apărut şi necesitatea specificării în codul instrucŃiunii a lungimii operanzilor ce vor fi
procesaŃi: 8 biŃi, 16 biŃi, 32 biŃi, 64 biŃi etc. O soluŃie tipică la această problemă constă în
includerea în formatul instrucŃiunii a unui câmp, să zicem de 2 biŃi, care va specifica
lungimea operandului/operanzilor procesaŃi: 00 -8 biŃi, 01 -16 biŃi, 10 -32 biŃi, 11 -64 biŃi.
Nu vom include în formatul instrucŃiunii pe care-l vom propune un astfel de câmp
considerând că toate transferurile vor fi pe 32 biŃi. Propunem ca exerciŃiu de proiectare
includerea unui astfel de câmp în format.
Unitatea cea mai mică adresabilă în memorie este octetul (8 biŃi). Pentru eficienŃă
codul instrucŃiunii nu trebuie să aibă o lungime arbitrară ci trebuie compus dintr-un număr
exact de octeŃi. Procesoarele CISC au de regulă instrucŃiuni de lungime variabilă.
Procesoarele RISC au instrucŃiuni de lungime fixă. Vom alege o lungime fixă pentru
instrucŃiune: 32 biŃi. Aceasta conduce la simplificarea decodificatorului instrucŃiunii.
Lungimea de 32 biŃi este uzuală în cazul RISC deşi nu este posibilă specificarea unei
constante pe 32 biŃi într-o instrucŃiune pe 32 biŃi. Vom specifica constante pe 16 biŃi şi
printr-o secvenŃă de două instrucŃiuni, un registru pe 32 biŃi va putea fi încărcat cu o

12
ARHITECTURA SISTEMELOR DE CALCUL

constantă pe 32 biŃi, compusă din două constante pe 16 biŃi. Această complicaŃie va fi


evitată la încărcarea constantei zero, operaŃie realizabilă printr-o singură instrucŃiune dacă
se utilizează R0 care conŃine permanent constanta zero pe 32 biŃi.

2.1.3. Lungimea adreselor de memorie

Utilizarea adreselor pe 32 biŃi este convenabilă dacă registrele procesorului au de


asemenea 32 biŃi. Utilizarea adreselor pe 64 biŃi ar fi o altă variantă care Ńinteşte în viitor.
Vom prevedea adrese pe 32 biŃi care asigură adresarea unei memorii interne de maxim 4
gigaocteŃi (232).

2.2. Formate de instrucŃiuni

Vom aloca 6 biŃi, biŃii 31 la 26, pentru câmpul principal de opcode, ceea ce va
permite codificarea a 64 instrucŃiuni diferite. În ideea extinderii numărului de instrucŃiuni,
pentru instrucŃiunile care nu utilizează toŃi biŃii rămaşi (biŃii 25 la 0), vom utiliza în anumite
cazuri un câmp secundar de sub-opcode. De exemplu, câmpul principal de opcode ar putea
specifica o clasă de instrucŃiuni (aritmetice), în timp ce câmpul sub-opcode va selecta
operaŃia (aritmetică) propriu-zisă. Vom avea cinci clase de instrucŃiuni:

2.2.1. Formatul registru – registru – registru (R-R-R)

Pentru eficienŃă şi viteză aceste instrucŃiuni vor opera numai cu operanzi preluaŃi
din registre. O operaŃie aritmetico-logică se va aplica celor doi operanzi preluaŃi din registre
iar rezultatul va fi depus tot într-un registru; 15 biŃi vor fi necesari pentru a specifica cele 3
registre.

Fig. 2.1. Formatul registru – registru – registru (formatul R-R-R)

Este de dorit să păstrăm câmpurile definite în formatul R-R-R pe aceleaşi poziŃii în


toate formatele pe care le vom defini ulterior. Aceasta înseamnă că toate instrucŃiunile care
vor avea un registru destinaŃie (Rd) vor utiliza biŃii 25 la 21 pentru selecŃia destinaŃiei şi
toate instrucŃiunile care utilizează două registre sursă vor utiliza biŃii 20 la 16 pentru
selecŃia sursei Rs1 şi respectiv biŃii 15 la 11 pentru selecŃia sursei Rs2. InstrucŃiunile care

13
Proiectarea setului de instrucŃiuni

utilizează un singur registru sursă, cum ar fi cele care operează cu un registru şi o constantă,
vor specifica unicul registru sursă în câmpul 20 la 16 (Rs1). BiŃii neutilizaŃi din codul
instrucŃiunii conduc la o slabă compactare a secvenŃelor de cod şi deci la o ineficientă
stocare a acestora în memorie. Dar nu acesta este factorul esenŃial care trebuie luat în
considerare; factorul esenŃial este viteza cu care instrucŃiunea poate fi decodificată şi
executată.
Un exemplu de instrucŃiune registru – registru – registru ar fi:

ADD R1,R4,R5 ; R1 = R4 + R5

Utilizând R0, care memorează permanent constanta zero, putem crea o instrucŃiune
“move”:

ADD R2,R3,R0 ; R2 = R3 (+0)

În consecinŃă, o instrucŃiune “move” registru – registru – registru specifică este nenecesară.


InstrucŃiunile aritmetice (care se încadrează în acest format) vor realiza operaŃii ca:
adunare, scădere, înmulŃire, împărŃire (operaŃii cu întregi), deplasare/rotire la stânga sau la
dreapta cu unul sau mai mulŃi biŃi, iar instrucŃiunile logice vor realiza operaŃii ca AND, OR,
NOT, XOR. Numerele reprezentate în virgulă flotantă vor avea operaŃii (instrucŃiuni)
proprii de adunare, scădere, înmulŃire şi împărŃire şi în acest context s-ar putea renunŃa la
instrucŃiunile de înmulŃire/împărŃire în virgulă fixă.
InstrucŃiunile de deplasare/rotire necesită numai un operand. Rs1 ar putea specifica
operandul deplasat iar Rs2 ar putea specifica numărul de poziŃii deplasate.
BiŃii neutilizaŃi (biŃii 10 la 0) ar putea fi utilizaŃi ca “sub-opcode” pentru o unitate
funcŃională cum ar fi ALU. Astfel, câmpul “opcode” va specifica o clasă de operaŃii (de
exemplu aritmetico-logice), iar câmpul “sub-opcode” va selecta operaŃia propriu-zisă la
ALU.

2.2.2. Formatul registru - registru - constantă (R-R-I)

Sunt foarte frecvente situaŃiile în care unul dintre operanzii unei instrucŃiuni
aritmetico-logice este o constantă. Pentru codificarea constantei respective se utilizează un
câmp din codul instrucŃiunii şi de aceea acest mod de adresare se numeşte imediat, iar
formatul se mai numeşte şi registru - registru - imediat.
Cel mai adesea constantele necesare sunt constante mici. O dimensiune rezonabilă
pentru aceste constante este 16 biŃi şi această dimensiune se încadrează bine în formatul din
fig. 2.2. Combinând două constante de 16 biŃi se obŃine o constantă pe 32 biŃi. Câmpurile
“opcode”, Rd şi Rs1 rămân pe aceleaşi poziŃii pe care au fost fixate în formatul R-R-R
(important pentru reducerea complexităŃii decodificatorului instrucŃiunii).
Un exemplu de instrucŃiune R-R-I ar fi:

ADD R4,R5,64 ; R4 = R5 + 64

14
ARHITECTURA SISTEMELOR DE CALCUL

Fig. 2.2. Formatul registru - registru - constantă (formatul R-R-I)

Formatul registru–registru-constantă poate fi utilizat cu toate operaŃiile aritmetico-


logice prevăzute pentru formatul R-R-R, inclusiv operaŃiile de deplasare/rotire în care
numărul de poziŃii deplasate va fi specificat de constanta utilizată.

2.2.3. Formatul registru - memorie (R-M)

Pentru că toate instrucŃiunile procesează operanzi preluaŃi din registre, aceştia


trebuie mai întâi transferaŃi din memorie în registre. InstrucŃiunile R-M (instrucŃiunile
“load/store”), prin care se vor realiza transferurile registru - memorie, trebuie să specifice
adresa locaŃiei de memorie ce va fi implicată în transfer, şi multe moduri de adresare pot fi
utilizate pentru adresarea locaŃiei respective. Totuşi, modul de adresare registru indirect cu
“offset” pe care îl vom implementa este un mod de bază din care derivă majoritatea
celorlalte moduri. În modul de adresare indirect registru, un registru specificat conŃine
adresa locaŃiei de memorie ce se va implica în transfer. OpŃional un “offset” dat de o
constantă memorată în codul instrucŃiunii poate fi adunat la conŃinutul registrului respectiv
pentru a genera adresa utilizată la accesarea memoriei. InstrucŃiunile “load” încarcă
conŃinutul locaŃiei respective în registrul destinaŃie în timp ce instrucŃiunile “store”
memorează registrul sursă în locaŃia respectivă.

LD R1,200[R8] ; conŃinutul locaŃiei de memorie adresată


; de R8 + 200 este încărcat în R1.
ST 16[R3],R4 ; R4 este copiat în locaŃia de memorie adresată
; de R3 + 16.

O primă variantă de format pentru instrucŃiunile “load/store” ar fi formatul R-R-I


din figura 2.3.
Pentru “load” Rd specifică registrul ce va fi încărcat în timp ce pentru “store” Rd
specifică registrul ce va fi copiat în memorie; în ambele cazuri Rs1 specifică registrul ce
conŃine adresa. Inevitabil, în cazul “load” Rd este destinaŃie iar în cazul “store“ Rd este
sursă ceea ce implică o complicaŃie minoră la proiectarea procesorului (decodificatorului
instrucŃiunii). ComplicaŃia poate fi evitată recurgând la formatul din figura 2.4. a cărui
deficienŃă constă în reducerea numărului de biŃi alocaŃi constantei de la 16 la 11 (offset în
domeniul -210 până la +210 -1).

15
Proiectarea setului de instrucŃiuni

Fig.2.3. Formatul “load/store“ - versiunea 1

Fig.2.4. Formatul “load/store” - versiunea 2

2.2.4. Formatul instrucŃiunilor de “branch”

În limbajele de nivel înalt apar puncte de decizie implementate, de exemplu, prin


declaraŃii IF:

if((x!=y)&&(z<0))
{
a=b-3 ;
b=b+4 ;
}

16
ARHITECTURA SISTEMELOR DE CALCUL

Compilatoarele trebuie să translateze astfel de declaraŃii în instrucŃiuni maşină.


Este neraŃional să prevedem câte o instrucŃiune maşină pentru fiecare declaraŃie IF (datorită
numărului vast de declaraŃii IF posibile). De asemenea, n-ar fi o idee bună încercarea de a
proiecta un set de instrucŃiuni maşină copiind instrucŃiunile unui anumit limbaj de nivel
înalt. Este evident că trebuie să extragem primitivele esenŃiale ale limbajelor de nivel înalt
şi acestea să fie implementate în limbajul maşină.
O construcŃie IF de orice complexitate poate fi descompusă în declaraŃii IF simple
de forma:

if (x relaŃie y ) goto L1

unde relaŃie poate fi orice relaŃie permisă în limbajele de nivel înalt: <, >, <=, >=, ==, !=.
De exemplu, secvenŃa C anterioară poate fi compilată într-o secvenŃă echivalentă
de instrucŃiuni maşină:

if (x==y) goto L1;


if (z>=0) goto L1;
a=b-3;
b=b+4;
L1:

Există mai multe posibilităŃi de implementare a declaraŃiei IF cu instrucŃiuni


maşină fiecare având un impact particular asupra proiectării procesorului.
Partea goto L1 revendică specificarea adresei de salt L1 de unde se va extrage
următoarea instrucŃiune în cazul în care condiŃia specificată în declaraŃia IF este îndeplinită.
Deoarece astfel de instrucŃiuni se utilizează pentru implementarea buclelor de program de
lungime relativ mică, pentru calculul adresei de salt se utilizează în general o adresare
relativă la PC (adresa de salt se obŃine adunând la PC-ul curent un “offset” specificat).
Acest mod de adresare permite compilatorului să genereze secvenŃe de cod relocabile care
pot fi încărcate în orice zonă de memorie fără schimbarea adreselor de “branch”. În
concluzie, instrucŃiunile de branch vor realiza salturi condiŃionate relative la PC (Program
Counter) .
AdiŃional sunt necesare şi salturi necondiŃionate pe care le vom realiza prin
instrucŃiuni jump.

A. Utilizarea registrului de condiŃii

Registrul de condiŃii sau de flag-uri este un registru special care caracterizează


rezultatele ALU obŃinute în cadrul instrucŃiunilor aritmetice:

Z - zero = 1 - caracterizează rezultat zero


= 0 - caracterizează rezultat diferit de zero

17
Proiectarea setului de instrucŃiuni

C - carry = 1 - caracterizează rezultat cu transport (împrumut)


= 0 - caracterizează rezultat fără transport (împrumut)
S - semn = 1 - caracterizează rezultat negativ
= 0 - caracterizează rezultat pozitiv
O - overflow = 1 - caracterizează rezultat cu depăşire
= 0 - caracterizează rezultat fără depăşire

Pentru a implementa o declaraŃie IF, mai întâi se execută o instrucŃiune aritmetică


poziŃionând flag-urile de condiŃii în acord cu rezultatul obŃinut. Cea mai utilizată este
instrucŃiunea de comparare care este similară cu instrucŃiunea de scădere, cu deosebirea că
rezultatul nu este depus la nici o destinaŃie ci doar se poziŃionează flag-urile în acord cu
valoarea sa. Apoi o instrucŃiune de branch condiŃionat examinează condiŃia testată şi, dacă
aceasta este îndeplinită, realizează saltul la adresa specificată. Există condiŃii pentru a căror
verificare trebuie examinate mai multe flag-uri.

O listă tipică de instrucŃiuni branch ar fi:

BL - branch if less – salt dacă este mai mic decât ( < )


BG - branch if greater – salt dacă este mai mare decât ( > )
BGE - branch if greater or equal – salt dacă este mai mare sau egal cu ( >= )
BLE - branch if less or equal – salt dacă este mai mic sau egal cu ( <= )
BE - branch if equal – salt dacă este egal cu ( == )
BNE - branch if not equal – salt dacă nu este egal cu ( != )

Considerând că compilatorul alocă variabilelor x şi y registrele R1 şi respectiv R2,


declaraŃia:

if (x==y) goto L1

poate fi translatată într-o secvenŃă de două instrucŃiuni maşină:

CMP R1,R2 ; poziŃionează flag-urile în acord cu rezultatul


; scăderii R1-R2
BE L1

Cele două instrucŃiuni trebuie executate în secvenŃă şi de aici rezultă o restricŃie


pentru compilatoarele cu reorganizare care nu pot introduce între cele două instrucŃiuni
decât instrucŃiuni care nu afectează flag-urile de condiŃii. De asemenea prima instrucŃiune
trebuie executată complet înainte de startarea celei de branch rezultând penalităŃi în cazul
procesoarelor pipeline. Registrul de condiŃii este o parte din ceea ce se numeşte starea
procesorului şi trebuie salvat la fiecare comutare de context.
Cu toate dezavantajele menŃionate registrul de condiŃii este încă foarte popular.

18
ARHITECTURA SISTEMELOR DE CALCUL

B. Evitarea utilizării unui registru de condiŃii

O soluŃie care evită atât utilizarea registrului de condiŃii cât şi necesitatea execuŃiei
succesive a celor două instrucŃiuni constă în combinarea celor două instrucŃiuni într-o
singură instrucŃiune de branch condiŃionat. Această instrucŃiune compară conŃinutul a două
registre şi execută saltul pe baza unei condiŃii specificate (de exemplu de egalitate):

BEQ R1,R2,L1 ; salt la L1 dacă R1 = R2

O astfel de instrucŃiune este necesară pentru fiecare condiŃie deşi instrucŃiunea BEQ în
combinaŃie cu o instrucŃiune BL (sau BG) formează un set care face posibil orice tip de test.
Să presupunem că dispunem şi de instrucŃiunea:

BL R1,R2,L1 ; salt la L1 dacă R1 < R2

Cele două instrucŃiuni (BEQ şi BL) sunt suficiente pentru a implementa toate tipurile de
test necesare:

CondiŃie SecvenŃa de cod aferentă

R1 < R2 BL R1,R2,L1

R1 > R2 BL R2,R1,L1

R1 >= R2 BL R2,R1,L1
BEQ R1,R2,L1

R1 <= R2 BL R1,R2,L1
BEQ R1,R2,L1

R1 == R2 BEQ R1,R2,L1

R1 != R2 BL R1,R2,L1
BL R2,R1,L1

Pentru a elimina secvenŃele de două instrucŃiuni, sunt necesare încă două


instrucŃiuni:

BGE - salt dacă este mai mare sau egal cu ...


BNE - salt dacă nu este egal cu ...

Testarea pe condiŃie de zero este o operaŃie foarte des utilizată în programe şi de


aceea pot fi prevăzute două instrucŃiuni speciale: BEQZ (“branch if zero”) şi BEQNZ
(“branch if not zero”).

19
Proiectarea setului de instrucŃiuni

BEQZ R3,L1 ; salt la adresa L1 dacă R3 == 0.


BEQNZ R3,L1 ; salt la adresa L1 dacă R3 != 0.

În cazul nostru aceste teste sunt uşor de realizat utilizând registrul R0 (care memorează
permanent constanta zero) şi instrucŃiunile BEQ şi BNE:

BEQ R3,R0,L1 ; salt la adresa L1 dacă R3 == 0.


BNE R3,R0,L1 ; salt la adresa L1 dacă R3 != 0.

Întotdeauna alegerea instrucŃiunilor în cazurile RISC este strâns dependentă de


modul de implementare al procesului şi de efectul pe care introducerea a câtorva noi
instrucŃiuni îl va avea asupra performanŃelor generale ale acestuia. CondiŃia de “egalitate”
revendică un comparator, care operează foarte rapid, în timp ce alte condiŃii cum ar fi “mai
mare sau egal”, revendică un sumator (scăzător), care operează mai lent.

C. OpŃiunea noastră privind instrucŃiunile branch

Considerăm oportună includerea în clasa branch a patru instrucŃiuni:

BEQ Ri,Rj,L1
BNE Ri,Rj,L1
BL Ri,Rj,L1
BGE Ri,Rj,L1

Aceste instrucŃiuni vor permite implementarea pe o singură instrucŃiune a oricărei


condiŃii de salt. Formatul cel mai potrivit pentru aceste instrucŃiuni este prezentat în fig.
2.5., unde Ri este Rd, Rj este Rs1 şi L1=PC+offset. Din nou utilizăm câmpul Rd pentru
selecŃia unui registru sursă şi nu destinaŃie.

Fig. 2.5. Formatul instrucŃiunilor de branch (format de tip R-R-I )

2.2.5. InstrucŃiunile de salt (jump)

InstrucŃiunea jump realizează un salt necondiŃionat la o adresă specificată în codul


instrucŃiunii. Aceste instrucŃiuni sunt necesare la implementarea construcŃiilor IF-THEN-
ELSE; sunt de asemenea utile la implementarea buclelor FOR şi WHILE în care condiŃia de

20
ARHITECTURA SISTEMELOR DE CALCUL

ieşire din buclă este calculată la începutul buclei. InstrucŃiunea jump va fi utilizată la
sfârşitul buclei pentru revenirea pe începutul acesteia. Utilizând mnemonica JMP, vom avea
instrucŃiunea:

JMP L1 ; salt la adresa L1

Adresa de salt L1 se obŃine adunând la PC offset-ul specificat în codul instrucŃiunii


(adresare relativă la PC ca în cazul instrucŃiunilor branch).

Fig. 2.6. Formatul instrucŃiunii jump (formatul I)

Să menŃionăm că şi instrucŃiunile branch pot fi făcute necondiŃionate. Un exemplu ar fi:

BEQ R1,R1,L1 ; salt dacă R1 = R1

InstrucŃiunile jump utilizează un offset pe 26 biŃi (fig. 2.6.) spre deosebire de


instrucŃiunile branch care utilizează un offset doar pe 16 biŃi. DistanŃa maximă de salt va fi
mult mai mare în cazul jump.
Atât în cazul branch cât şi în cazul jump ar putea fi folosit şi un al doilea mod de
adresare, modul registru - indirect. În acest caz în instrucŃiune este specificat explicit un
registru (altul decât registrul PC) care conŃine adresa instrucŃiunii pe care se va executa
saltul (fig. 2.7.).

Fig. 2.7. Formatul instrucŃiunii jump cu mod de adresare indirect - registru

Astfel de instrucŃiuni ar putea fi utile la implementarea declaraŃiilor SWITCH/CASE din


limbajele de nivel înalt şi pentru revenirea din proceduri.
Cu formatul din figura 2.7. putem avea, de exemplu:

JMP [R1] ; salt la instrucŃiunea a cărei adresă este


; conŃinută în R1

21
Proiectarea setului de instrucŃiuni

sau chiar:

JMP 134[R2] ; salt la instrucŃiunea a cărei adresă se obŃine


; adunând R2 + 134.

Să notăm că, în aceste cazuri, adresa de salt este o adresă absolută şi nu relativă la
PC deşi, dacă se dovedeşte util, ea ar putea fi interpretată şi ca adresă relativă. Să mai
notăm că notaŃia [R1] utilizată aici nu înseamnă “conŃinutul locaŃiei de memorie a cărei
adresă este dată de R1“ ca în cazul instrucŃiunilor load/store.

2.2.6. Apelul procedurilor

O facilitate a limbajelor de nivel înalt este aceea de a permite organizarea şi


execuŃia procedurilor. O secvenŃă de instrucŃiuni care se repetă de mai multe ori pe
parcursul unui program se organizează într-o procedură care se apelează din diverse puncte
ale programului principal. După fiecare execuŃie procedura returnează controlul
programului principal printr-o revenire pe instrucŃiunea următoare celei care a realizat
apelul procedurii. Procedurile pot fi imbricate (o procedură apelează altă procedură, care
apoi apelează altă procedură, ... etc.). De regulă este permis ca o procedură să se apeleze pe
ea însăşi (proceduri recursive). La apel, procedurii i se transmit de regulă parametrii care
vor fi utilizaŃi în calculele executate în interiorul procedurii. La sfârşitul execuŃiei
procedurile pot returna valori.
Două mecanisme esenŃiale trebuie să funcŃioneze pentru implementarea
procedurilor:

- mecanismul de apel şi respectiv de revenire din procedură.


- mecanismul de transmitere a parametrilor procedurii şi de returnare a
rezultatelor obŃinute în procedură.

A. InstrucŃiunile CALL/RET

În cazul procesoarelor CISC două instrucŃiuni speciale sunt prevăzute pentru


apelul procedurilor (instrucŃiunea CALL) şi pentru revenirea din proceduri (instrucŃiunea
RET).
InstrucŃiunea CALL salvează în stivă adresa de revenire (adresa instrucŃiunii ce
urmează după CALL) şi apoi execută un salt necondiŃionat la adresa de start a procedurii.
InstrucŃiunea RET de la sfârşitul procedurii realizează revenirea în programul principal
citind adresa de revenire din stivă şi executând un salt necondiŃionat la această adresă (fig.
2.8).

22
ARHITECTURA SISTEMELOR DE CALCUL

B. Stiva

Stiva este o structură de date de tip coadă care funcŃionează pe principiul LIFO
(Last-In-First-Out). Stivele pot fi implementate în memoria principală sau utilizând registre
interne procesorului. Stiva a fost preferată în memorie (mai cu seamă în cazul procesoarelor
CISC) datorită numărului aproape nelimitat de apeluri imbricate sau recursive. Un registru
special al procesorului numit SP (Stack Pointer) memorează permanent adresa vârfului
stivei. La memorarea unui cuvânt (de exemplu, de 32 biŃi) în stivă, mai întâi este
decrementat cu 4 registrul SP (cuvântul este format din 4 octeŃi) şi apoi cuvântul respectiv
este scris în memorie la adresa SP. La citirea unui cuvânt din stivă, mai întâi se citeşte
locaŃia de la adresa SP şi apoi SP este incrementat cu 4. A rezultat astfel o stivă care creşte
în jos (depunerea în stivă se face cu decrementare de adresă).

Fig.2.8. Apeluri de procedură prin instrucŃiuni CALL/RET

Stiva poate fi creată şi în interiorul procesorului utilizând un set de registre


dedicate. Avantajul stivelor interne este viteza operaŃiilor cu stiva care va fi mult
superioară. În cazul RISC se preferă stivele interne deşi, în această variantă, stiva va
conŃine un număr finit şi relativ mic de locaŃii.

C. Transferul parametrilor prin stivă

Procesoarele care execută instrucŃiuni CALL/RET execută şi instrucŃiuni


PUSH/POP pentru salvare/restaurare date în/din stivă. InstrucŃiunea PUSH decrementează
registrul SP şi apoi memorează data specificată (registrul specificat) la această adresă.

23
Proiectarea setului de instrucŃiuni

InstrucŃiunea POP citeşte locaŃia adresată de SP (vârful stivei) şi o plasează în registrul


specificat, după care incrementează registrul SP. Transferul parametrilor se realizează prin
instrucŃiuni PUSH/POP. Înainte de apelul procedurii (CALL) în programul principal
parametrii sunt memoraŃi în stivă prin instrucŃiuni PUSH, iar după apel (în procedură)
parametrii sunt preluaŃi din stivă prin instrucŃiuni POP.

D. Utilizarea ferestrei de registre pentru transferul parametrilor şi


pentru variabile locale

Deoarece procedurile sunt foarte utilizate în multe aplicaŃii, salvarea şi restaurarea


registrelor la apelul procedurilor şi respectiv revenirea din proceduri consumă o parte
semnificativă din timpul procesorului afectând negativ performanŃele acestuia. Proiectul
RISC elaborat la Universitatea Berkeley (1985) introducea conceptul ferestrei de registre
(register window) prin care un set de registre interne era utilizat pentru simplificarea şi
creşterea vitezei de transmitere a parametrilor între procedurile imbricate. Era prevăzut un
număr de registre locale pentru fiecare procedură. Ideea a fost preluată în câteva dintre
următoarele procesoare printre care şi procesorul SUN Sparc.
Principiul “register window” presupune implementarea în cadrul procesorului a
unui set amplu de registre care va memora adresele de revenire şi parametrii transferaŃi
între proceduri (fig. 2.9.).

Set de registre
Registre disponibile
tuturor procedurilor Pointer-ul de fereastră
(variabile globale) (selectează fereastra curentă)

Registre pentru procedura 1

parametrii de ieşire din procedura 1


şi respectiv de intrare în procedura 2
Registre pentru
procedura 2
parametrii de ieşire din procedura 2
şi respectiv de intrare în procedura 3
Registre pentru procedura 3

Registre pentru
procedura 4

Fig. 2.9. Fereastra de registre implementată în procesoare RISC

24
ARHITECTURA SISTEMELOR DE CALCUL

Fiecare procedură poate accesa un subset de registre alocat procedurii respective în


cadrul setului de registre. Subsetul alocat unei proceduri este denumit fereastră de registre
(register window). Registrele din centrul ferestrei sunt utilizate numai de procedura
respectivă. Registrele din partea superioară a ferestrei sunt accesate de procedura respectivă
şi de procedura care a apelat-o, iar registrele din partea inferioară de procedura respectivă şi
procedura apelată de aceasta. Atât partea superioară cât şi partea inferioară a ferestrei se
suprapune peste porŃiuni similare alocate altor proceduri. Când o procedură este apelată de
către altă procedură (iniŃial de către programul principal), fereastra se mută pe poziŃia
imediat următoare, iar la revenirea din procedură fereastra se mută înapoi. Presupunând că
setul va conŃine un număr suficient de registre pentru imbricarea procedurilor, putem afirma
că nu mai este necesară salvarea parametrilor şi a adresei de revenire în memorie. Setul de
registre este gestionat de un registru pointer de fereastră care identifică permanent fereastra
curentă. Un al doilea set de registre accesibil tuturor procedurilor este prevăzut pentru
variabilele globale.
Analizând diverse programe s-a constatat că, de regulă, numărul de proceduri
imbricate nu este mai mare de 8 şi extrem de rar depăşeşte 11, iar depăşirea accidentală a
acestor limite se face pentru perioade de timp rezonabil de scurte. Pentru exploatarea
eficientă a acestor caracteristici setul de registre este adresat într-o manieră circulară. Un
exemplu specific ar fi procesorul RISC II realizat la Universitatea Berkeley, care are în total
138 registre configurate în 8 ferestre a câte 32 registre fiecare, plus 10 registre globale.
Aranjarea circulară a celor 8 ferestre de registre este prezentată în figura 2.10.

Fig. 2.10. ConfiguraŃia circulară a ferestrelor de registre la procesorul RISC II

25
Proiectarea setului de instrucŃiuni

Pointerul ferestrei curente (CWP - Current Window Pointer) are 3 biŃi şi selectează
permanent fereastra care va fi accesată. Registrul care va fi accesat în cadrul ferestrei va fi
specificat în instrucŃiune prin numărul său (0 - 31). Registrele numerotate de la 0 la 9 referă
întotdeauna registrele globale indiferent de numărul ferestrei curente. Registrele globale
sunt accesibile tuturor procedurilor. Registrele numerotate de la 10 la 31 referă întotdeauna
registre din cadrul ferestrei curente. Adresa efectivă a unui registru din setul R10 - R31 se
obŃine prin concatenarea celor 3 biŃi ce formează adresa de fereastră (conŃinutul CWP) cu
cei 5 biŃi care specifică adresa registrului în cadrul ferestrei. Să observăm că prin
suprapunerea ferestrelor apar grupuri de registre care răspund la două adrese. De exemplu,
registrul 0:26 din fereastra 0 (programul principal) este în acelaşi timp şi registrul 1:10 din
fereastra 1 (procedură pe primul nivel de imbricare).
În general numărul procedurilor imbricate este limitat şi aranjamentul circular al
ferestrelor se potriveşte bine acestei caracteristici. Ori de câte ori acest număr depăşeşte
valoarea 8, va trebui utilizată memoria principală pentru salvarea conŃinutului anumitor
registre. Un alt dezavantaj potenŃial apare în sistemele de operare multitasking, la
comutarea task-urilor; salvarea contextului consumă timp suplimentar (număr mare de
registre).

E. OpŃiunea noastră privind mecanismul de apel al procedurilor

OpŃiunea are la bază două considerente. În primul rând considerăm oportună


evitarea instrucŃiunilor complexe de tip CALL/RET care vor crea probleme în cazul
implementării procesorului în tehnică pipeline (instrucŃiuni specifice CISC). În al doilea
rând, pentru că apelul procedurilor poate fi foarte frecvent, considerăm oportună evitarea
utilizării memoriei pentru memorarea adreselor de revenire, a parametrilor şi pentru
salvarea registrelor. Dacă operaŃiile sunt frecvente, ar trebui implementate în acord cu
filozofia RISC. Principiul ferestrelor de registre este atractiv şi oportun pentru că utilizează
registre şi pentru modul eficient de transmitere a parametrilor. În cazurile în care numărul
procedurilor imbricate depăşeşte numărul ferestrelor trebuie recurs la memorie pentru
salvarea adreselor de revenire şi transmiterea parametrilor.
O ultimă posibilitate constă în transformarea instrucŃiunilor CALL/RET în
secvenŃe de instrucŃiuni simple. Un singur registru intern va fi utilizat pentru memorarea
adresei de revenire: R31. O instrucŃiune CALL simplificată, numită JAL (Jump And Link),
va executa saltul la adresa specificată în instrucŃiune şi va memora adresa de revenire în
R31. Pentru revenirea din procedură se poate utiliza un simplu salt necondiŃionat la
instrucŃiunea a cărei adresă este dată de R31; va fi suficientă o instrucŃiune JMP cu mod de
adresare indirect - registru. InstrucŃiunea JAL poate utiliza formatul I din figura 2.6.
Mecanismul va funcŃiona evident pentru un singur nivel de apel. Pentru imbricare, R31 va
fi memorat în stivă, utilizând un al doilea registru ca pointer de stivă: R29. În esenŃă, se
creează o stivă în vârful căreia se va afla R31, iar restul locaŃiilor se vor afla în memorie.
SecvenŃa de cod necesară pentru apelul şi revenirea dintr-o procedură va fi:

26
ARHITECTURA SISTEMELOR DE CALCUL

SUB R29,R29,4 ; decrementează pointerul de stivă (4 octeŃi)


ST [R29],R31 ; memorează ultima adresă de revenire în stivă
JAL Proc_Label ; salt la Proc_Label şi memorează adresa de
; revenire în R31.
LD R31,0[R29] ; după revenirea din procedură, se restaurează
; adresa de revenire anterioară în R31.
ADD R29,R29,4 ; incrementează pointerul de stivă (4 octeŃi)

Revenirea de la sfârşitul procedurii va fi simplă:

JMP [R31] ; salt la locaŃia a cărei adresă se află în R31

Există două alternative pentru salvarea registrelor: salvare înainte de apelul


procedurii (salvarea executată de către apelant) şi respectiv după apel (salvarea executată de
către apelat). Pentru memorarea parametrilor în stivă, înainte de apel, va fi necesară o
secvenŃă de forma:

SUB R29,R29,4
ST [R29],R31
SUB R29,R29,4
ST [R29],Parametru1
SUB R29,R29,4
ST [R29],Parametru2
JAL Proc_Label

După definirea principalelor formate de instrucŃiune se poate trece la proiectarea


procesorului. Evident că vor trebui incluse în setul de instrucŃiuni prezentat şi alte
instrucŃiuni, dar putem considera că toate aceste instrucŃiuni noi se vor încadra în formatele
deja descrise. InstrucŃiunile descrise sunt specifice filozofiei RISC.

2.3. ExecuŃia instrucŃiunilor

ExecuŃia instrucŃiunilor se face în paşi elementari succesivi. În fiecare pas


elementar se vor executa anumite operaŃii simple, interne procesorului.

2.3.1. Structura procesorului

Structura internă a procesorului este prezentată în figura 2.11. În structură pot fi


identificate registrele generale R0 - R31 şi un număr de registre specializate:

PC - Program Counter - conŃine permanent adresa următoarei instrucŃiuni de


executat

27
Proiectarea setului de instrucŃiuni

IR - Instruction Register - conŃine codul instrucŃiunii curente (în curs de


execuŃie)
MAR - Memory Address Register - conŃine adresa locaŃiei de memorie ce va fi
accesată în timpul unei operaŃii de citire/scriere memorie.
MDR - Memory Data Register - conŃine data trimisă spre memorie (la scriere) şi
respectiv data recepŃionată din memorie (la citire)
A - registru tampon - memorează conŃinutul registrului sursă Rs1 selectat în
setul de registre generale
B - registru tampon - memorează conŃinutul registrului sursă Rs2 selectat în
setul de registre generale
C - registru tampon - conŃine valoarea ce va fi memorată în registrul destinaŃie
Rd selectat în setul de registre generale

Fig. 2.11. Structura procesorului cu control centralizat

28
ARHITECTURA SISTEMELOR DE CALCUL

În structură mai apare:

ALU -unitatea aritmetico-logică în care se vor executa operaŃiile


aritmetice şi logice
Unitate de control -va genera semnalele de comandă pentru realizarea transferurilor de
date şi a altor operaŃii interne procesorului. Va utiliza conŃinutul
registrului IR (codul instrucŃiunii curente) pentru a determina ce
comenzi trebuie să genereze şi în ce secvenŃă. InstrucŃiuni diferite
vor impune secvenŃe de comenzi diferite. SecvenŃierea în timp a
comenzilor se va face pe baza semnalului de tact al procesorului.

În structură mai apar 3 busuri interne (busurile S1, S2 şi D) care interconectează


registrele şi ALU. Primele două busuri, S1 şi S2, sunt dedicate celor doi operanzi sursă
posibil de specificat în instrucŃiune. S1 şi S2 transportă operanzii pe intrările ALU. Busul D
transportă rezultatele ALU la destinaŃia specificată în instrucŃiune. Structura cu trei busuri
este specifică formatului de instrucŃiune cu trei adrese (de registru).
Cele două registre, MAR şi MDR, au fost prevăzute pentru interfaŃarea
procesorului cu memoria şi nu sunt accesibile programatorului (nu pot fi specificate în nici
o instrucŃiune maşină). Înaintea oricărui acces la memorie, în MAR va fi încărcată adresa
locaŃiei ce urmează a se accesa. În instrucŃiunile LD (load), MDR va fi încărcat cu datele
citite din memorie , iar în instrucŃiunile ST (store), MDR va fi încărcat de către procesor cu
datele ce vor fi scrise în memorie.
Registrele A, B şi C sunt de asemenea inaccesibile programatorului şi au fost
prevăzute pentru interfaŃarea setului de registre generale R31 - R0. Registrele A şi B vor fi
încărcate cu datele citite din registrele sursă specificate în instrucŃiune (Rs1 şi Rs2) iar
registrul C va fi încărcat cu datele ce urmează a fi depuse în registrul destinaŃie specificat
în instrucŃiune (Rd).
Setul de registre generale are structura unei memorii multiport sincronă rapidă cu
32 locaŃii a câte 32 biŃi, care va avea 3 surse de adresare:

- câmpul Rs1 din codul instrucŃiunii pentru citirea primului registru sursă în A
- câmpul Rs2 din codul instrucŃiunii pentru citirea celui de-al doilea registru
sursă în B
- câmpul Rd din codul instrucŃiunii pentru scrierea datelor din C în registrul
destinaŃie specificat.

Pentru descrierea transferurilor interne de date vom utiliza notaŃia:

Rj ← Ri ; conŃinutul registrului Ri este transferat în registrul Rj

În structura din figura 2.11. aceste transferuri pot fi realizate numai prin intermediul ALU,
ceea ce implică:

29
Proiectarea setului de instrucŃiuni

a) ALUR ← Ri ; sursa Ri se aplică pe intrarea ALU şi se transferă


; pe ieşirile ALU ( ALUR )
b) Rj ← ALUR ; ieşirile ALUR se transferă în registrul destinaŃie Rj

Pentru transferul a) este utilizat unul din busurile sursă (S1 sau S2), iar pentru transferul b)
este utilizat busul destinaŃie (D). Cele două transferuri sunt simultane ceea ce înseamnă că,
global, transferul Rj←Ri se va executa într-o singură perioadă de tact. Registrele Ri şi Rj
trebuie să fie registre conectate direct la busuri. Registrele generale R31-R0 nu sunt
conectate direct şi de aceea vor realiza transferuri prin intermediul registrelor tampon
A,B,C.

2.3.2. Ciclul fetch instrucŃiune

În acest ciclu, registrul PC conŃine adresa instrucŃiunii ce urmează a se citi din


memorie. Această adresă va fi transferată în MAR de unde va fi aplicată pe liniile de adresă
ale memoriei. După o întârziere datorată timpului de acces la memorie, cuvântul de 32 biŃi
citit din locaŃia selectată (codul instrucŃiunii) va fi încărcat în MDR prin intermediul liniilor
de date ale memoriei. InstrucŃiunea este apoi transferată din MDR în IR şi PC este
incrementat cu 4 pentru a pointa pe următoarea instrucŃiune în memorie (codul instrucŃiunii
conŃine 4 octeŃi). Cele trei acŃiuni (operaŃii) din cadrul ciclului fetch instrucŃiune sunt:

MAR ← PC ; se încarcă în MAR adresa instrucŃiunii


IR ← MDR ; se încarcă în IR codul instrucŃiunii citit din memorie
PC ← PC + 4 ; incrementare PC (codul instrucŃiunii de lungime fixă -
; 4 octeŃi)

Prima operaŃie trebuie executată înaintea celei de a doua, dar a doua şi a treia pot fi
executate simultan dacă incrementarea registrului PC nu implică utilizarea ALU (registrul
PC implementat cu logică specială de incrementare). EvidenŃiind operaŃiile simultane,
ciclul fetch instrucŃiune devine:

MAR ← PC
IR ← MDR , PC ← PC + 4

Procesorul operează sincron astfel că fiecare operaŃie sau grup de operaŃii simultane
startează la începutul perioadei de tact. Ciclul fetch instrucŃiune este independent de tipul
instrucŃiunii şi conŃine întotdeauna aceleaşi operaŃii. Procesarea unei instrucŃiuni începe
întotdeauna cu ciclul (faza) fetch instrucŃiune.

30
ARHITECTURA SISTEMELOR DE CALCUL

2.3.3. Ciclul de execuŃie

A doua fază, faza de execuŃie a instrucŃiunii, are un conŃinut dependent de tipul


instrucŃiunii ce urmează a se executa. În cazul instrucŃiunilor aritmetico-logice, de exemplu,
cei doi operanzi trebuie preluaŃi din registrele sursă specificate în codul instrucŃiunii şi
transferaŃi în registrele tampon A şi respectiv B:

A ← Rs1
B ← Rs2

BiŃii IR20 - 16 din codul instrucŃiunii selectează registrul Rs1, iar biŃii IR15 - 11 selectează
registrul Rs2 (fig. 2.1.). Deoarece cele două câmpuri de selecŃie a registrelor sursă sunt
situate, în general, pe aceleaşi poziŃii indiferent de tipul instrucŃiunii, este posibilă
extragerea lor şi adresarea setului de registre generale înainte de decodificarea instrucŃiunii
(decodificarea câmpului opcode). Putem, de asemenea, permite ca cele două operaŃii de
transfer a registrelor sursă în registrele A şi respectiv B să se facă automat pentru toate
instrucŃiunile chiar dacă cei doi operanzi sursă nu vor fi utilizaŃi (cum ar fi cazul
instrucŃiunii de salt necondiŃionat JMP care poate să nu specifice nici o sursă - vezi fig.
2.6.). Pentru aceste instrucŃiuni care nu au operanzi sursă, conŃinutul registrelor A şi B nu
va mai fi utilizat ulterior. Aceasta nu conduce la o degradare a performanŃelor procesorului
deoarece am prevăzut căi de date dedicate şi independente între setul de registre generale şi
registrele tampon A şi B. Dacă setul RG (registre generale) este implementat ca o memorie
multiport atunci cele 2 operaŃii pot fi executate simultan:

A ← Rs1 , B ← Rs2

Am prevăzut, de asemenea, o cale de date dedicată între registrul C şi setul RG care va fi


utilizată la memorarea rezultatului în registrul destinaŃie.
Următoarele operaŃii depind de tipul sau clasa instrucŃiunii ce urmează a se
executa. Tipul instrucŃiunii este codificat în câmpul opcode şi va fi cunoscut doar după
decodificarea acestui câmp. Câmpul opcode va fi decodificat în unitatea de control.

A. InstrucŃiunile aritmetico-logice R-R-R

ExecuŃia instrucŃiunilor aritmetico-logice, cum ar fi ADD R1,R2,R3,


presupune în continuare următoarele operaŃii:
- transferul registrelor A şi B (cei doi operanzi sursă) pe intrările ALU. A va fi
transferat pe busul S1, iar B pe busul S2.
- transferul rezultatului obŃinut pe ieşirile ALU în registrul C; acest transfer va
fi efectuat pe busul D.
- transferul registrului C în registrul destinaŃie adresat în setul RG cu câmpul
IR25 - 21 din codul instrucŃiunii (fig. 2.1.).

31
Proiectarea setului de instrucŃiuni

În concluzie:

C ← A <operaŃie> B
Rd ← C

Cele două operaŃii specificate pot fi descompuse, specificând şi busurile:

S1bus ← A , S2bus ← B
Dbus ← S1bus <operaŃie> S2bus
C ← Dbus

OperaŃia ALU va fi specificată prin decodificarea câmpului opcode (sau sub-opcode dacă
există).

B. InstrucŃiunile aritmetico-logice R-R-I

InstrucŃiunile aritmetico-logice care utilizează două registre şi o constantă sunt


similare cu cele care utilizează trei registre cu excepŃia că locul celui de-al doilea registru
sursă este preluat de constanta specificată în câmpul IR15 - 0 din codul instrucŃiunii (fig. 2.2).
Utilizând notaŃia IR15 - 0 pentru a specifica constanta, vom avea:

C ← A <operaŃie> IR15-0

Constanta poate fi extrasă din codul instrucŃiunii (aflat în IR) pe unul din busurile S1 sau S2
(fig. 2.11.) de unde va fi aplicată pe una din intrările ALU.
Să ne reamintim că nu am prevăzut o instrucŃiune specială de transfer (move)
registru-registru. Transferurile registru-registru pot fi executate numai prin ALU utilizând
instrucŃiunea ADD în care unul dintre operanzi va fi R0 (constanta zero).

C. InstrucŃiunile cu referire la memorie (load/store)

În formatul instrucŃiunilor load/store - versiunea 1 (fig. 2.3.), adresa locaŃiei de


memorie este specificată de conŃinutul registrului sursă Rs1 la care se adaugă un offset
codificat în câmpul IR15 - 0 al codului instrucŃiunii. Adresa astfel calculată trebuie încărcată
în registrul MAR:

MAR ← A + IR15-0

Această adunare poate fi efectuată în ALU. Următoarele operaŃii sunt dependente de tipul
referinŃei la memorie: load sau store.

32
ARHITECTURA SISTEMELOR DE CALCUL

În cazul instrucŃiunilor load, conŃinutul locaŃiei adresate în memorie va fi


transferat prin intermediul registrelor MDR şi C în registrul destinaŃie Rd selectat de
câmpul IR25 - 21 din codul instrucŃiunii. SecvenŃa completă va fi:

MAR ← A + IR15-0 ; fixarea adresei de acces


C ← MDR ; încărcarea datelor citite din memorie
Rd ← C ; transferul datelor citite în Rd

Un timp acoperitor trebuie să treacă (timpul de acces la memorie) din momentul încărcării
adresei în MAR şi până la transferul datelor din MDR în C.
Pentru instrucŃiunile store ne confruntăm cu o excepŃie: registrul sursă este
specificat în câmpul destinaŃie al codului instrucŃiunii (IR25 - 21). O primă soluŃie ar fi ca în
primul pas al fazei de execuŃie, simultan cu încărcarea registrelor A şi B, să fie încărcat şi
registrul C cu conŃinutul registrului destinaŃie:

A ← Rs1 , B ← Rs2 , C ← Rd

După acest prim pas conŃinutul registrului C va fi emis spre memorie prin intermediul
registrului MDR. SecvenŃa completă pentru execuŃie va fi:

MAR ← A + IR15-0 ; fixarea adresei de acces


MDR ← C ; fixarea datelor de scris în memorie

Acest principiu impune implementarea setului RG cu trei porturi de citire. O soluŃie


alternativă, care păstrează adresa registrului sursă în câmpul destinaŃie al codului
instrucŃiunii (IR25 - 21), constă în utilizarea unui hardware de redirectare atunci când este
decodificată o instrucŃiune store. Acest hardware, activat pe durata fazei de execuŃie a
instrucŃiunilor store, determină utilizarea registrului B în locul registrului C. SecvenŃa de
operaŃii ce compun ciclul de execuŃie devine:

A ← Rs1 , B ← Rd ; acŃionează hardware -ul de redirectare


MAR ← A + IR15-0
MDR ← B ; acŃionează hardware -ul de redirectare

În acord cu structura procesorului din figura 2.11., în ultimele două operaŃii (încărcarea
adresei în MAR şi respectiv a datelor de scris în memorie în MDR), traseul datelor
transferate trece prin ALU. Din acest motiv cele două operaŃii nu pot fi executate simultan.
Dacă în structura procesorului s-ar implementa o cale de date directă între registrele B şi
MDR atunci cele două transferuri ar fi putut fi simultane.

33
Proiectarea setului de instrucŃiuni

D. InstrucŃiunile de branch

În faza de execuŃie a instrucŃiunilor de branch trebuie verificată condiŃia de salt


specificată în instrucŃiune. Dacă condiŃia este adevărată, atunci se va calcula adresa de salt
şi se va încărca în PC. CondiŃiile de salt, stabilite pe baza registrelor Rs1 şi Rs2 (vezi
paragraful 2.2.4 C), pot fi verificate examinând rezultatul scăderii Rs1 - Rs2:

condiŃie ← A <operaŃie> B

Adresa de salt se calculează adunând offset-ul specificat în instrucŃiune (fig. 2.5.) la adresa
curentă din PC:

ALUR ← PC + IR15-0

Cu resurse hard suficiente, adresa de salt poate fi calculată simultan cu evaluarea condiŃiei
de salt. Din păcate, calculul adresei de salt revendică ALU şi busurile de date interne.
Acesta e motivul pentru care anumite procesoare RISC operează cu o singură condiŃie de
branch, A = 0, care poate fi evaluată utilizând un hardware simplu şi rapid de detecŃie de
zero.
Pasul final din faza de execuŃie constă în încărcarea adresei de salt în PC dacă este
îndeplinită condiŃia testată:

IF CondiŃie=TRUE THEN PC ← ALUR

În caz contrar, încărcarea în PC se inhibă şi se va trece la următoarea instrucŃiune din


secvenŃă.

E. InstrucŃiunile de salt (jump)

Realizează salturi necondiŃionate relative la PC prin simpla adunare a offset-ului


specificat în instrucŃiune la conŃinutul registrului PC. Deoarece avem de-a face cu un offset
pe 26 biŃi, va fi necesar un hardware de validare, activat pe durata execuŃiei instrucŃiunii
JMP, şi care va valida transferul întregului offset (IR25 - 0) pe busul intern. În aceste condiŃii
execuŃia devine:

PC ← PC + IR25-0

Pentru instrucŃiunile jump cu adresare indirectă-registru, ca de exemplu JMP123[R4],


secvenŃa de execuŃie va fi:

PC ← A + IR15-0

34
ARHITECTURA SISTEMELOR DE CALCUL

Registrul specificat a fost încărcat în A în pasul anterior, iar offset-ul are doar 16 biŃi
(fig.2.7.).
InstrucŃiunea de apel procedură, JAL, este similară cu instrucŃiunea JMP;
suplimentar JAL va încărca adresa de revenire în R31. ExecuŃia instrucŃiunii JAL va fi:

R31 ← PC
PC ← PC + IR25-0

Deoarece registrul PC a fost incrementat deja în ciclul fetch instrucŃiune, în R31 se va


încărca adresa instrucŃiunii ce urmează după JAL în secvenŃă.

F. InstrucŃiunile de control

Sunt instrucŃiuni cel mai adesea fără operanzi şi care specifică doar o operaŃie.
InstrucŃiunea NOP (No OPeration) este prezentă în orice set de instrucŃiuni. Este utilizată la
separarea dependenŃelor între instrucŃiuni (procesoare pipeline) şi la depanarea programelor
când NOP înlocuieşte instrucŃiunile eliminate. Cel mai convenabil cod pentru NOP este
zero (32 biŃi de 0) ceea ce înseamnă că o memorie iniŃializată cu zero va conŃine numai
instrucŃiuni NOP.
InstrucŃiunea HALT opreşte procesorul (inhibă semnalul de tact). Ieşirea din
această stare de oprire se poate face, de regulă, numai printr-o întrerupere sau prin
iniŃializarea procesorului (RESET).

35
Proiectarea setului de instrucŃiuni

36
ARHITECTURA SISTEMELOR DE CALCUL

3. MEMORII CACHE

Memoria cache este o memorie de capacitate relativ mică dar de viteză foarte
ridicată care se intercalează între procesor şi memoria principală a sistemului (memoria
centrală). Pentru creşterea performanŃelor unui sistem de calcul, principial există două
direcŃii posibile:

1. creşterea vitezei de procesare a instrucŃiunilor în interiorul procesorului.


2. creşterea vitezei cu care datele circulă în interiorul sistemului.

Pentru obŃinerea unor performanŃe globale superioare trebuie acŃionat concertat şi corelat pe
ambele direcŃii. Memoria cache este introdusă în sistem pentru a reduce timpul efectiv de
acces la memoria principală şi deci vizează creşterea vitezei de transfer a datelor în cadrul
sistemului. Toate calculatoarele moderne conŃin memorii cache.

3.1. Principiul de funcŃionare al memoriei cache

Viteza la care pot fi accesate locaŃiile de memorie reprezintă un factor critic la


proiectarea sistemului. Viteza memoriilor semiconductoare este caracterizată prin 2
parametrii: timpul de acces şi ciclul memoriei. Timpul de acces la memorie este dat de
timpul scurs din momentul activării unei cereri de acces la memorie (emisia adresei) până
în momentul încheierii transferului informaŃiei din sau în locaŃia accesată. În mod normal,
timpii de acces pentru operaŃiile de citire şi respectiv scriere memorie sunt identici. Ciclul
memoriei este dat de timpul minim dintre două accese succesive la memorie (citire sau
scriere). Uneori timpul de acces şi ciclul memoriei sunt aproape identici. Aceasta înseamnă
că imediat ce o locaŃie a fost citită/scrisă, un alt acces la memorie poate fi iniŃiat. Adesea
însă, după încheierea transferului de date, o scurtă perioadă de timp este necesară pentru
relaxarea circuitelor interne şi pregătirea acestora pentru următoarea operaŃie de scriere/
citire (perioada de preîncărcare pentru anumite tehnologii semiconductoare). În cazul
memoriilor de mare viteză ciclul memoriei reprezintă aproape dublul timpului de acces.
Procesoarele sunt capabile în general să execute operaŃii (asupra operanzilor) mult
mai rapide comparativ cu timpul de acces la memoria principală (diferenŃa este de
aproximativ un ordin de mărime). Deşi există memorii semiconductoare care pot opera la
viteze comparabile cu viteza de operare a procesorului, este neeconomică implementarea
întregii memorii principale cu astfel de chip-uri de memorie de mare viteză. Decalajul de
viteză poate fi redus substanŃial introducând între procesor şi memoria principală un bloc de
memorie mic dar de mare viteză numit cache (fig. 3.1).
Memoria cache constă dintr-o memorie RAM de viteză foarte mare care va opera
la viteza pe care procesorul o revendică. InstrucŃiunile programului şi datele sunt transferate

37
Memorii cache

în cache şi accesate apoi aici de către procesor. În mod normal programele şi datele sunt
încărcate şi păstrate în memoria principală (MP) astfel că memoria cache va conŃine copiile
unor locaŃii din memoria principală (vezi locaŃia X din fig. 3.1). Pentru fiecare locaŃie MP
copiată în cache este necesar ca în cache să se memoreze şi adresa din MP a locaŃiei
respective astfel încât procesorul să poată adresa cache-ul cu aceleaşi adrese cu care
adresează şi MP. Aceasta înseamnă că la orice acces la memorie procesorul va utiliza
adresa MP. Dacă locaŃia MP respectivă are o copie în cache procesorul va accesa această
copie, iar dacă locaŃia MP respectivă nu are o copie în cache procesorul va accesa chiar
locaŃia MP respectivă. FuncŃionarea cache-ului devine astfel transparentă. Orice cuvânt de
date care urmează a fi scris în memorie de către procesor va fi scris (în primul rând) în
cache şi scris şi în MP, fie în acelaşi timp, fie ulterior când locaŃia cache respectivă trebuie
să preia copia unei alte locaŃii MP (cache-ul fiind de dimensiune redusă va putea reŃine doar
copiile aferente unui subset de locaŃii MP).

Memoria principală

Transfer de date

Memoria cache X

Transfer de date

Procesor

Fig. 3.1. Principiul memoriei cache

Anumite caracteristici ale programelor au fost determinante pentru succesul


memoriilor cache. Dacă programele ar fi avut o execuŃie pur secvenŃială, de la o anumită
adresă de memorie în sus, şi dacă aceleaşi instrucŃiuni n-ar fi fost niciodată reexecutate,
atunci cache-ul ar fi introdus întârzieri suplimentare deoarece informaŃia ar fi trebuit mai
întâi transferată din MP în cache şi apoi în procesor şi viceversa. Timpul de acces ar fi fost:

38
ARHITECTURA SISTEMELOR DE CALCUL

ta = tm + tc (3.1)

unde: tm = timpul de acces la MP


tc = timpul de acces la cache

Din fericire, deşi codul este în general executat secvenŃial, de fapt toate
programele repetă anumite secŃiuni de cod şi repetă şi accesele la aceleaşi date. Aceste
caracteristici sunt cuprinse în principiul localizării care se aplică la ambele tipuri de
referinŃe la memorie (referinŃe la instrucŃiuni şi respectiv date), deşi este mult mai evident
în cazul referinŃelor la instrucŃiuni. Principiul localizării are două componente:

1. localizarea temporală (localizarea în timp). Odată referite, anumite locaŃii vor


fi foarte probabil referite din nou, în viitorul apropiat.
2. localizarea spaŃială (localizarea în spaŃiu). ReferinŃele la memorie (inclusiv
cele la următoarea locaŃie) se fac cel mai adesea în apropierea (vecinătatea)
ultimei locaŃii referite.

ReferinŃele la următoarea locaŃie sunt uneori grupate într-o a treia componentă:


localizarea secvenŃială.
Localizarea temporală o găsim în buclele de instrucŃiuni, stivele de date şi accesele
aleatoare. Localizarea spaŃială descrie caracteristica programelor de a accesa un număr de
zone distincte în memorie. Localizarea secvenŃială descrie modul de referire secvenŃială a
locaŃiilor (instrucŃiunilor) care este o caracteristică de bază a programelor. Localizarea
secvenŃială apare şi la accesarea structurilor de date deoarece elementele unei structuri sunt
adesea memorate în locaŃii secvenŃiale. Localizarea temporală este esenŃială pentru eficienŃa
cache-ului. Localizarea spaŃială este utilă la proiectarea cache-ului, dar nu este esenŃială.

3.1.1. Exploatarea avantajelor localizării temporale

Programele conŃin bucle şi în general buclele sunt scurte. După încărcarea în cache
a unei bucle de program, instrucŃiunile din buclă vor fi reaccesate în cache la fiecare reluare
a buclei respective. Accesarea unor noi instrucŃiuni în MP se va face doar la ieşirea din
buclă. Presupunând că bucla este reluată de n ori atunci, la prima parcurgere a buclei
instrucŃiunile vor fi accesate în MP şi copiate în cache, iar următoarele n-1 parcurgeri se
vor realiza cu accesarea instrucŃiunilor în cache.
Timpul mediu de acces la instrucŃiunile buclei respective va fi:

(n ⋅ t c + t m ) t
Timp mediu de acces = = tc + m (3.2)
n n

Dacă tc = 25 ns, tm = 200 ns şi n = 10, timpul mediu de acces va fi 45 ns. Fără


cache timpul de acces ar fi 200 ns. În concluzie, utilizând un cache de opt ori mai rapid

39
Memorii cache

decât MP (200/25) se obŃine o creştere substanŃială a vitezei de transfer procesor - memorie.


Să notăm că, pe măsură ce n creşte, timpul mediu de acces se apropie asimptotic de
valoarea tc. Creşterea vitezei de transfer depinde de program. Anumite programe pot fi
caracterizate de o puternică localizare temporală, în timp ce alte programe nu. De
asemenea, timpul mediu de acces dă doar o indicaŃie aproximativă privitoare la creşterea
performanŃelor globale ale sistemului. Creşterea reală va fi diferită deoarece, pe lângă
timpii de fetch instrucŃiune şi fetch operand, ciclul instrucŃiunii mai conŃine şi alte
componente.

3.1.2. Exploatarea avantajelor localizării spaŃiale

Pentru a obŃine avantaje din localizarea spaŃială, vom transfera nu numai un octet
sau un cuvânt din MP în cache (şi viceversa) ci un număr de locaŃii secvenŃiale care
formează o linie sau un bloc. Pentru performanŃe maxime, linia (blocul) trebuie transferată
simultan prin intermediul unui bus de date extins, preluând câte un octet sau un cuvânt din
fiecare modul de memorie principală. Organizarea memoriei MP în mai multe module
conectate la memoria cache prin intermediul unui bus de date extins permite şi egalizarea
timpilor de acces la cache şi respectiv MP. Structura de principiu este redată în fig. 3.2
(vezi şi paragraful 1.2). În exemplul din fig. 3.2, opt module de memorie creează o linie de
opt octeŃi pentru cache. Adresele sunt distribuite succesiv celor 8 module de memorie astfel
încât octeŃi succesivi sunt locaŃi în module succesive, aşa cum indică figura 3.2. Câmpul
superior de adresă (câmpul Linie) este transmis tuturor modulelor pentru a selecta o locaŃie
în cadrul fiecărui modul. Cei mai puŃin semnificativi 3 biŃi (câmpul Byte) identifică octetul
(modulul din care provine octetul respectiv). Deci opt locaŃii consecutive pot fi citite în
cache, sau scrise din cache în MP, simultan. Desigur că această tehnică presupune că cei
opt octeŃi consecutivi sunt şi necesari (procesorului).
Numărul de module de memorie, în cazul general m, se alege astfel încât să rezulte
o egalizare a vitezelor de operare aferente cache-ului şi respectiv MP. Pentru o egalizare
perfectă m va fi ales astfel încât:

m · tc = tm

Cuvintele (octeŃii) din cadrul unei linii cache vor putea fi accesate de procesor în
ordine secvenŃială în alte m·tc secunde. Deci, timpul mediu de acces la aceste cuvinte, când
sunt pentru prima dată referite, va fi 2·m·tc / m = 2·tc . Dacă aceste cuvinte vor fi referite de
n ori (buclă de program), timpul mediu de acces va fi:

2 ⋅ t c + (n - 1) ⋅ t c (n + 1) ⋅ t c
Timp mediu de acces = = (3.3)
n n

De exemplu, dacă tc = 25 ns şi tm = 200 ns, opt module de MP vor permite


transferul în cache a opt cuvinte în 200 ns.

40
ARHITECTURA SISTEMELOR DE CALCUL

MP formată din 8 module de memorie

8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7

Byte

Linie Byte

Linie
Adresă Memorie Cache

Procesor

Fig. 3.2. Memorie cache interfaŃată cu 8 module de memorie principală


(memorie cu cuvânt de lungime extinsă )

Pentru n = 10, vom avea:

(50 + 9 ⋅ 25)
Timpul mediu de acces = = 27,5 ns
10

Pentru valori mari ale lui n timpul mediu de acces va fi aproximativ tc.
Să notăm că dacă localizarea în cadrul programelor s-ar reduce doar la localizarea
secvenŃială a instrucŃiunilor, şi dacă instrucŃiunile ar fi întotdeauna adresate şi localizate
secvenŃial, memoria cache n-ar mai fi necesară deoarece o memorie principală cu lungimea
cuvântului extinsă împreună cu un buffer extins plasat între procesor şi MP ar fi suficiente
pentru alimentarea procesorului cu instrucŃiuni la rata solicitată de către acesta (vezi 1.2.A).
Totuşi, situaŃia reală este alta şi excepŃiile de la principiul localizării secvenŃiale atât în ceea
ce priveşte fetch-ul instrucŃiunilor cât şi referinŃele la date trebuie luate în considerare.
Pentru fetch-ul unui cuvânt am presupus că este necesară accesarea cache-ului
înainte de accesarea MP, că este deci uzual să se caute întâi în cache pentru a vedea dacă
informaŃia solicitată există acolo sau nu. Avantajul cache-ului rezultă din informaŃiile pe
care acesta le conŃine, deşi atunci când procesorul referă un cuvânt inexistent în cache ar fi
necesară o a doua referinŃă la cache după ce cuvântul a fost transferat din MP în cache (vezi
relaŃia 3.1). Cu hardware adiŃional corespunzător, capabil să gestioneze şi un bus de date
direct procesor - MP, performanŃele pot fi îmbunătăŃite în sensul că un cuvânt citit din MP
poate fi transmis simultan spre cache şi respectiv spre procesor (se elimină cea de-a doua
referinŃă la cache).

41
Memorii cache

OperaŃiile de scriere necesită o gestiune specială care va fi prezentată la 3.3. Orice


cuvânt scris în cache trebuie (eventual) transferat şi în MP şi acest transfer va reduce timpul
mediu de acces. Vom deduce formulele pentru calculul timpului mediu de acces Ńinând cont
şi de operaŃiile de scriere, dar pentru început vom lua în considerare doar operaŃiile de
citire. Formulele pe care le vom obŃine pot fi aplicate atât la calculul timpului mediu de
acces cât şi la calculul ciclului mediu.

3.1.3. Rata de HIT

Probabilitatea ca un cuvânt solicitat să fie deja actualizat în cache depinde de


program şi de dimensiunea şi organizarea cache-ului; tipic 70-90% din referinŃele la
memorie vor găsi cuvintele solicitate în cache. Accesul în care cuvântul solicitat este găsit
în cache este acces cu hit. Când cuvântul referit nu se află în cache şi drept consecinŃă
trebuie accesat în MP vom avea un acces cu miss. Rata de hit, h, se defineşte ca:

Numarul de referinte la memorie cu hit in cache


h=
Numarul total de referinte la memorie

Rata de hit reprezintă şi probabilitatea ca un cuvânt să fie găsit în cache. Rata de miss este
dată de 1 - h. Timpul mediu de acces, ta, este dat de:

ta = tc + (1-h) ·tm (3.4)

presupunând din nou că pentru fetch-ul unui cuvânt se accesează mai întâi cache-ul şi, în
caz de miss, se accesează apoi şi MP. Accesele la MP adaugă timpul (1-h)·tm. De exemplu,
dacă rata de hit este 0,85 (o valoare tipică), timpul de acces la MP este 100 ns şi timpul de
acces la cache este 25 ns, atunci timpul mediu de acces va fi 25+0,15·100 = 35 ns.
Rearanjând ecuaŃia (3.4) obŃinem:

ta t
= 1 + (1-h ) ⋅ m (3.5)
tc tc

Obiectivul urmărit este de a obŃine pentru raportul ta/tc o valoare cât mai apropiată
de 1 ceea ce este posibil atunci când h se apropie de 1 şi când raportul tm/tc se apropie de
valoarea 1. Pentru memoriile cache implementate în sistemele actuale raportul tm/tc ia
valori în domeniul [2, 10]. În acest caz, pentru h în domeniul 70-90%, raportul ta/tc ia valori
apropiate de 1.
În cele ce urmează vom considera că atunci când data este citită din MP în cache
(miss) aceasta va fi imediat disponibilă şi pentru procesor fără a mai fi nevoie de o nouă
citire din cache (există un bus de date direct între MP şi procesor).
Există diverse interpretări care se dau timpului de acces. De exemplu, timpul de
acces la cache, tc, este compus din timpul necesar interogării cache-ului (pentru a descoperi

42
ARHITECTURA SISTEMELOR DE CALCUL

dacă data căutată este prezentă sau nu în cache) şi timpul necesar producerii (citirii) acestei
date. Dacă data solicitată nu este prezentă în cache, atunci sunt necesare tm secunde pentru a
transfera data din MP în procesor (incluzând orice timp adiŃional de încărcare a datei
respective în cache). Dacă separăm tc în tci (timp de interogare a cache-ului) şi tcr (timp de
citire din cache), relaŃia (3.4) devine:

ta = tci+ h·tcr + (1-h)·tm (3.6)

sau:

ta = h·(tci+ tcr) + (1-h)·(tci +tm) (3.7)

adică, timpul de acces este (tci + tcr) dacă data este prezentă în cache (timp de hit) şi
respectiv (tci +tm) dacă data nu este prezentă în cache (timp de miss).
EcuaŃia (3.6) poate fi rearanjată:

ta = tci + tcr + (1-h)·(tm - tcr) (3.8)

sau:

ta = thit + (1-h)·tmiss-pen (3.9)

unde:
thit = timpul de acces când data se află în cache
tmiss-pen = timpul suplimentar care se adaugă atunci când data nu se află în cache
(miss penalty)

În practică, timpul de acces se exprimă în cicluri maşină şi nu în secunde. Ciclul


maşină reprezintă ciclul (perioada) tactului aplicat procesorului. De asemenea şi timpul de
procesare aferent diferitelor instrucŃiuni se exprimă în cicli maşină. Tipic thit este 1 - 2 cicli
maşină iar tmiss-pen este 5 - 20 cicli.

3.2. Moduri de organizare a memoriilor cache

Există mai multe variante de implementare a memoriilor cache. În toate variantele


procesorul accesează memoria cache cu adresa locaŃiei MP ce conŃine data solicitată. Deci
memoria cache, indiferent de structura sa internă, trebuie să folosească adresa MP pentru a
selecta intern data solicitată de procesor (dacă aceasta este memorată în cache) sau să
semnaleze miss (dacă data solicitată nu se află memorată în cache). Maparea locaŃiilor MP
în cache precum şi transferul datelor din MP în cache şi invers trebuie gestionate la nivel
hardware; pentru eficienŃă maximă cache-ul trebuie să fie complet transparent la nivel
software.

43
Memorii cache

3.2.1. Memoria cache complet asociativă

Cea mai simplă metodă de a asocia data memorată în cache cu adresa locaŃiei MP
de unde provine este de a memora în aceeaşi locaŃie cache atât data cât şi adresa MP de
unde aceasta provine. Acesta este principiul mapării complet asociative (fully associative
cache). Pentru implementarea cache-urilor complet asociative se utilizează memorii
asociative (memorii adresabile prin conŃinut). În fiecare locaŃie cache se memorează atât
adresa MP cât şi data memorată în MP la acea adresă. Când procesorul lansează o citire din
memorie, adresa MP este comparată cu toate adresele memorate în cache (memorie
asociativă) aşa cum se indică în figura 3.3.
Dacă o locaŃie cache raportează egalitate (hit), câmpul Data din locaŃia respectivă este citit
şi încărcat în procesor (locaŃia cache respectivă a fost încărcată anterior cu datele conŃinute
în locaŃia MP selectată cu adresa emisă de procesor). Dacă compararea nu detectează
egalitate pe nici o locaŃie cache (miss), atunci procesorul va accesa şi va citi data solicitată
din MP. Dacă partea asociativă din cache (zona "Adresa MP") este capabilă să memoreze
întreaga adresă MP (fără trunchiere), atunci orice locaŃie MP poate fi actualizată
(memorată) în orice locaŃie cache.

Dacă adresa nu este găsită


Adresa MP emisă de procesor
în cache se accesează MP ( miss)
Memoria
Principală

Memoria cache

Comparare simultană Adresa MP Data


cu toate adresele memorate
în cache

Validare acces în
MP la miss
Validare acces la
hit (adresă găsită)

Procesorul accesează
locaŃia (hit)

Fig. 3.3. Memoria cache complet asociativă

44
ARHITECTURA SISTEMELOR DE CALCUL

Pentru a exploata avantajele localizării spaŃiale (în toate tipurile de cache), într-o
locaŃie cache se poate memora mai mult decât o locaŃie MP (o linie sau un bloc de locaŃii
MP consecutive). În figura 3.4., o linie cache este constituită din 4 cuvinte (locaŃii) MP
consecutive, fiecare cuvânt MP fiind format din 4 octeŃi. Cea mai puŃin semnificativă parte
din adresa emisă de procesor (câmpul Byte) selectează octetul, câmpul următor (câmpul
word) selectează cuvântul în cache, iar biŃii cei mai semnificativi care rămân se compară cu
adresele memorate în cache. Întreaga linie poate fi transferată printr-o singură tranzacŃie
cache - MP dacă se implementează un bus de date extins între cache şi MP. Cu un bus
redus (de dimensiunea unui cuvânt), cuvintele unei linii trebuie transferate în tranzacŃii
succesive, şi drept consecinŃă un bit adiŃional trebuie memorat în cache alături de fiecare
cuvânt pentru a indica starea de validitate/invaliditate a cuvântului respectiv (la un moment
dat anumite cuvinte din cadrul liniei pot fi valide şi altele nu şi această stare este descrisă cu
ajutorul biŃilor de validare).
Uzual unitatea adresabilă în MP este octetul. Patru octeŃi consecutivi formează un
cuvânt de 32 biŃi. Procesorul poate iniŃia citirea unui octet, cuvânt de 16 biŃi, cuvânt de 32
biŃi (sau chiar mai mare). Există diverse tehnici utilizate pentru specificarea dimensiunii
cuvântului adresat în MP. În cadrul acestei lucrări vom considera că procesorul generează
adrese de byte şi prin câteva semnale adiŃionale specifică dimensiunea cuvântului ce
urmează a fi transferat (un octet, 2 octeŃi, 4 octeŃi, mai mulŃi octeŃi). Patru octeŃi reprezintă
o dimensiune convenabilă pentru linia cache deoarece aceasta coincide cu lungimea unei
instrucŃiuni de 32 biŃi. O linie cache de 8 octeŃi va găzdui două instrucŃiuni pe 32 biŃi. Deşi
dimensiunea minimă a liniei pare a fi 4 octeŃi totuşi va fi necesară accesarea individuală a
octeŃilor în cadrul liniei; aceasta se realizează cu ajutorul câmpurilor word şi byte din cadrul
adresei emise de procesor (fig. 3.4).
Cache-ul complet asociativ oferă flexibilitate maximă în ceea ce priveşte
combinarea liniilor în cache (orice linie MP poate fi încărcată în orice locaŃie cache) şi
pentru o anumită capacitate a cache-ului oferă minimum de conflict, dar este în acelaşi timp
şi cel mai scump datorită costului memoriilor asociative (zona cache în care se memorează
adresele MP este un plan de memorie asociativă). În ciclurile miss informaŃia solicitată de
procesor se va citi din MP şi linia din care provine această informaŃie trebuie actualizată
(copiată) în cache înlocuind astfel o altă linie actualizată anterior în cache. Linia care va fi
înlocuită va fi selectată pe baza unui algoritm de înlocuire şi acest algoritm trebuie
implementat în hardware deoarece trebuie să opereze la viteză ridicată. Implementarea
complet asociativă este viabilă (din punct de vedere al costului) doar pentru cache-uri de
capacitate mică până la moderată. Microprocesoarele cu cache-uri interne (on-chip) mici
folosesc frecvent implementarea complet asociativă deoarece asigură performanŃe maxime.

BiŃii de validare

În toate cache-urile, dacă dimensiunea liniei este mai mare decât dimensiunea
busului de date cache - MP, vor fi necesare mai multe transferuri pentru a umple o linie
cache cu cuvinte din MP şi respectiv pentru a transfera liniile modificate în cache (prin
cicluri de scriere date în memorie executate de procesor) înapoi în MP.

45
Memorii cache

Adresa MP emisă de procesor


Word Byte
2 2

M e m o r i a c a c h e
Linie

Adresa MP Word 0 Word 1 Word 2 Word 3


Comparare simultană
cu toate adresele memorate
în cache

Validare acces la hit SelecŃie Word şi


(adresă găsită) respectiv Byte

Procesorul accesează cuvântul


(octetul) din cadrul liniei (hit)

Fig. 3.4. Cache complet asociativ cu linii multicuvânt

Deoarece cuvintele sunt transferate în cache succesiv este posibil ca la un moment dat o
linie cache să nu conŃină toate cuvintele asociate liniei respective; o parte dintre cuvinte
sunt încă neactualizate şi deci aparŃin liniei anterioare care fusese memorată în cache în
aceeaşi locaŃie. Pentru a gestiona astfel de situaŃii, fiecare cuvânt cache este prevăzut cu un
bit de validare care este setat atunci când cuvântul face într-adevăr parte din linia a cărei
adresă este memorată în cache în linia respectivă. Când un cuvânt este încărcat în cache,
bitul său de validare este setat. Câmpul de adresă din cadrul unei linii cache identifică linia,
deşi nu toate cuvintele din linia respectivă aparŃin cu adevărat liniei curente; unele dintre
cuvinte sunt moştenite din linia precedentă. Când procesorul accesează cache-ul, adresa
emisă de procesor este comparată cu toate adresele memorate în cache. Dacă se obŃine o
corespondenŃă (egalitate), linia respectivă este selectată şi bitul de validare asociat
cuvântului selectat (în cadrul liniei) este verificat pentru a se vedea dacă cuvântul respectiv
este o parte validă a liniei sau nu. Dacă este valid (bitul de validare setat), cuvântul este

46
ARHITECTURA SISTEMELOR DE CALCUL

accesat în cache, în caz contrar cuvântul va fi citit din MP, încărcat în procesor şi simultan
actualizat (scris) în cache. La actualizarea cuvântului în cache pot apărea 2 situaŃii:

1. în cache există o linie a cărei adresă memorată coincide cu adresa locaŃiei MP


de unde provine cuvântul ce trebuie actualizat (linia a fost creată anterior prin
actualizarea altui cuvânt din cadrul liniei). În acest caz cuvântul va fi
actualizat în poziŃia sa naturală din cadrul liniei respective şi bitul său de
validare va fi setat.

2. în cache nu există nici o linie a cărei adresă memorată coincide cu adresa


locaŃiei MP de unde provine cuvântul ce trebuie actualizat (linia trebuie creată
acum deoarece se actualizează primul cuvânt din cadrul acestei linii). În acest
caz trebuie selectată o linie cache pe baza unui algoritm implementat în
hardware (de exemplu algoritmul LRU - Least Recently Used line). Cuvântul
este actualizat în poziŃia corespunzătoare din linia respectivă, bitul său de
validare este setat şi câmpul de adresă al liniei respective este actualizat cu
adresa MP de unde provine cuvântul respectiv. ToŃi biŃii de validare din linia
respectivă, exceptând cel asociat noului cuvânt actualizat, sunt resetaŃi.
Practic, s-a evacuat linia cea mai puŃin recent utilizată din cache şi în locul ei
s-a actualizat acest prim cuvânt din cadrul unei noi linii. Următoarele cuvinte
vor fi încărcate pe măsură ce acestea vor fi solicitate de către procesor şi
actualizarea acestora se va face în acord cu cele prezentate la punctul 1 de mai
sus.

Termenul sub-bloc este utilizat pentru a descrie entitatea care necesită un bit de
validare. Pentru un bus de date de 32 biŃi între cache şi MP, sub-blocul va avea 32 biŃi;
pentru un bus de 64 biŃi acesta va avea 64 biŃi, etc. Chiar dacă o întreagă linie poate fi
transferată din MP în cache printr-un singur transfer pe bus, biŃii de validare sunt în general
necesari în toate tipurile de cache pentru a gestiona perioadele de "start-up" ale sistemului
când cache-ul are un conŃinut aleator.

3.2.2. Memoria cache cu mapare directă

Memoria cache complet asociativă este costisitoare deoarece revendică un plan de


memorie asociativă a cărui structură devine foarte complexă pe măsură ce creşte
capacitatea cache-ului. Cache-urile cu mecanism de adresare prin mapare directă utilizează
memorie RAM normală de mare viteză. Structura de principiu a unei astfel de memorii
cache este redată în fig. 3.5.
Adresa MP emisă de procesor este împărŃită în două câmpuri, Tag şi index. Tag-ul
este format din biŃii cei mai semnificativi ai adresei şi este memorat în cache împreună cu
data. Index-ul este format din biŃii cei mai puŃin semnificativi şi este utilizat la adresarea
cache-ului.

47
Memorii cache

Când procesorul referă memoria, index-ul este mai întâi utilizat pentru a selecta o
locaŃie cache. Apoi tag-ul memorat în locaŃia respectivă este citit şi comparat cu tag-ul
rezultat din adresa emisă de procesor. Dacă cele 2 tag-uri sunt identice (hit) data citită din
cache se încarcă în procesor. Dacă cele 2 tag-uri sunt diferite (miss) se accesează MP. Se
citeşte locaŃia MP adresată şi cuvântul citit se încarcă în cache (în locaŃia deja selectată cu
index). Dacă există un bus de date direct procesor - MP este posibil ca informaŃia să se
încarce simultan şi în procesor (read - through la miss).

Adresa MP emisă de procesor


Tag Adresa completă
Index
(Tag şi Index) Memoria
Memoria cache Principală
0
Index

Tag Data i

Read
N
Comparator
= =
Validare acces
în MP la miss

Validare acces la
hit (adresă găsită)

Procesorul accesează
locaŃia (hit)

Fig. 3.5. Memoria cache cu mapare directă

În cazul unei operaŃii de scriere locaŃia cache (identic selectată) va fi modificată (scrisă).
LocaŃia MP aferentă poate fi modificată în acelaşi timp (write-through) sau mai târziu
(write-back). OperaŃiile de scriere vor fi discutate în secŃiunea 3.2.2.
În fig. 3.6 se prezintă un cache cu mapare directă care conŃine în cadrul unei linii
mai multe cuvinte. Adresa MP este compusă din câmpurile tag, line (sau index) şi word
care selectează cuvântul în cadrul liniei cache. Tag-ul este asociat liniei (toate cuvintele din
cadrul unei linii au acelaşi tag). Câmpul line (index) este utilizat pentru adresarea memoriei
cache şi tag-ul memorat în linia cache selectată este comparat cu tag-ul rezultat din adresa
emisă de procesor. În cazul operaŃiilor de citire, dacă cele 2 tag-uri sunt identice (hit), se

48
ARHITECTURA SISTEMELOR DE CALCUL

citeşte cuvântul selectat în cadrul liniei cache selectate şi se încarcă în procesor. Dacă cele
2 tag-uri sunt diferite (miss), linia ce conŃine cuvântul dorit este mai întâi transferată din
MP în cache.

Adresa MP emisă de procesor


Tag Index Word Byte

M e m o r i a c a c h e
Index

Tag Word 0 Word 1 Word 2 Word 3

Read

Comparator
= = Validare acces

Validare acces la hit SelecŃie Word în MP (miss)

Procesorul accesează cuvântul


(octetul) din cadrul liniei (hit)

Fig. 3.6. Cache cu mapare directă cu linii multicuvânt

În cazul mapării directe, o linie din MP cu un anumit index va fi mapată


întotdeauna în aceeaşi locaŃie cache (în cea selectată de index-ul respectiv), şi deci la un
moment dat în cache se pot afla doar linii cu indecşi diferiŃi. Deoarece o linie MP poate fi
găzduită de o singură locaŃie cache, un algoritm de înlocuire (evacuare) devine nenecesar.
EficienŃa înlocuirii liniilor cache în cazul mapării directe rezidă din probabilitatea foarte
mică ca două linii MP diferite dar cu acelaşi index să fie revendicate de procesor în aceeaşi
perioadă de timp. Totuşi, astfel de situaŃii pot să apară, de exemplu, într-o instrucŃiune
vectorială (pe şiruri de elemente), când 2 vectori de date (şiruri) sunt memoraŃi în MP
începând de la adrese fizice diferite dar cu indecşi identici şi când perechi de elemente
vectoriale trebuie procesate împreună. Pentru performanŃe maxime, structurile de date şi
vectorii trebuie memoraŃi în MP într-o manieră care minimizează "conflictele" cache în
timpul procesării perechilor de elemente. În fig. 3.6. câmpul index din adresa MP emisă de
procesor adresează direct locaŃiile cache. Este posibilă introducerea unei funcŃii care
mapează index-ul conŃinut în adresă într-un alt index (diferit valoric) utilizat pentru

49
Memorii cache

adresarea locaŃiilor cache. Această tehnică şi avantajele ei vor fi prezentate în cazul TLB
(Translation Look-aside Buffer), în capitolul 4.
Pentru cache-urile cu mapare directă pot fi identificate următoarele avantaje:

1. Nu necesită algoritm de înlocuire (evacuare)


2. Hardware simplu şi cost scăzut
3. Viteză mare de operare

Dezavantajele sunt:

1. PerformanŃele scad considerabil dacă în aceeaşi perioadă de timp se


accesează adrese MP diferite dar care prezintă câmpuri index identice.

2. Rata de hit este mai mică decât în cazul cache-urilor asociative.

Totuşi, pe măsură ce capacitatea cache-ului creşte diferenŃa dintre ratele de hit aferente
celor 2 tipuri de cache-uri se reduce şi devine nesemnificativă.

3.2.3. Memoria cache organizată în seturi asociative

În cazul memoriei cache cu mapare directă, toate cuvintele (liniile) memorate în


cache trebuie să aibă indecşi diferiŃi. Tag-urile pot fi identice sau diferite. Deci o linie MP
poate fi copiată într-o singură locaŃie cache. În cazul memoriei cache complet asociative,
orice linie MP poate fi copiată în orice locaŃie cache, dar costul devine prohibitiv pentru
cache-urile de capacitate mare şi memoriile asociative de capacitate mare devin relativ
lente (operaŃia de căutare în memoria asociativă consumă tot mai mult timp pe măsură ce
capacitatea acesteia creşte).
Cache-urile organizate în seturi asociative permit doar unui număr limitat de linii
MP, cu acelaşi index şi tag-uri diferite, să fie încărcate în cache şi deci ar putea fi
considerate ca un compromis între maparea complet asociativă şi maparea directă.
Organizarea unui cache cu seturi asociative este prezentată în fig. 3.7.
Cache-ul este împărŃit în "seturi" de linii iar asociativitatea se rezumă doar la
locaŃiile (liniile) ce compun un set. Dacă, de exemplu, cache-ul conŃine 4 linii în cadrul
fiecărui set (ca în fig. 3.7) atunci asociativitatea se rezumă doar la cele 4 linii din cadrul
setului şi cache-ul va fi format din seturi asociative a câte 4 locaŃii (four-way set associative
cache). Numărul de locaŃii (linii) dintr-un set reprezintă dimensiunea setului şi se numeşte
asociativitate. Fiecare linie din fiecare set conŃine un tag memorat care împreună cu index-
ul (numărul setului) identifică complet linia respectivă. Mai întâi, index-ul din adresa MP
emisă de procesor va selecta un set în cache. Apoi, comparatoarele vor compara toate tag-
urile din setul selectat cu tag-ul desprins din adresa emisă de procesor. Dacă un comparator
semnalizează egalitate (hit), linia aferentă este accesată şi încărcată în procesor. Dacă nici
un comparator nu semnalizează egalitate (miss), se va recurge la accesul în MP.

50
ARHITECTURA SISTEMELOR DE CALCUL

Câmpul tag se alege întotdeauna ca fiind cel mai semnificativ în cadrul adresei MP
emisă de procesor. Este urmat de câmpul index care selectează setul (linia), iar câmpul
word/byte reprezintă partea cea mai puŃin semnificativă din adresă. Acest format este cel
mai performant deoarece linii consecutive din MP vor fi distribuite în seturi cache
succesive (vezi 3.1.1. – 3.1.3.) şi este utilizat în toate sistemele cunoscute. Să notăm că
pentru un cache organizat în seturi asociative poziŃia relativă a celor 3 câmpuri poate fi
oricare şi se stabileşte în faza de proiectare.

Adresa MP emisă de procesor


Tag Index Word

M e m o r i a c a c h e
Index

Line Line Line Line


Tag Data Tag Data Tag Data Tag Data

Comparatoare
= = = = = = = = Validare acces

în MP (miss)
Validare acces Validare acces Validare acces Validare acces
la hit la hit la hit la hit

SelecŃie Word

Procesorul accesează cuvântul


(octetul) din cadrul liniei validate (hit)

Fig. 3.7. Cache cu seturi asociative

Compararea tag-urilor memorate în setul selectat, cu tag-ul desprins din adresa


emisă de procesor se poate face în paralel şi toate informaŃiile din cache (tag şi data) pot fi
memorate în memorii RAM rapide (nu sunt necesare memorii asociative pentru
implementarea cache-ului). Numărul de comparatoare necesare în organizarea cu seturi
asociative este dat de numărul de linii din set şi nu de numărul total de linii din cache cum
se întâmplă în organizarea complet asociativă. În cache-ul complet asociativ, fiecare tag
necesită propriul comparator şi, din acest motiv, cache-ul trebuie implementat cu memorii

51
Memorii cache

asociative (adresabile prin conŃinut). În cazul cache-ului organizat în seturi asociative, setul
poate fi selectat rapid (pe baza index-ului) şi toate liniile din set pot fi citite în paralel şi
simultan cu citirea tag-urilor pentru comparare. După compararea tag-urilor (presupunând
că se obŃine hit), linia corespondentă mai trebuie doar selectată.
Algoritmul de înlocuire (evacuare) aplicat la cache-ul organizat în seturi asociative
trebuie să ia în considerare doar liniile din componenŃa setului deoarece setul este
predeterminat prin index. Deci, cu două linii în fiecare set, de exemplu, un singur bit
adiŃional ar fi suficient pentru a specifica linia ce trebuie înlocuită (evacuată). Tipic,
dimensiunea setului este 2, 4, 8 sau 16 linii. Când dimensiunea setului este 1 organizarea cu
seturi asociative se reduce la organizarea cu mapare directă iar când cache-ul conŃine un
singur set se reduce la organizarea complet asociativă. Numărul total de linii din cache este
dat de 2 parametri:

Numărul total de linii în cache = (număr seturi) · (număr linii în set)

Pentru un anumit număr total de linii (capacitate cache), valorile celor 2 parametrii se
stabilesc la proiectare (evaluări de performanŃe).
Organizarea în seturi asociative este foarte populară în cache-urile interne
implementate în microprocesoarele actuale şi poate fi găsită la Motorola MC 68040 (4-way
set associative), Intel 486 (4-way set associative), Intel i860 (4-way set associative), Intel
Pentium (2-way set associative), etc.

3.2.4. Organizarea în sectoare

În cazul organizării sectoriale, MP şi cache-ul sunt împărŃite în sectoare, fiecare


sector conŃinând un număr de linii. Orice sector din MP poate fi actualizat în orice sector
din cache (asociativitate la nivel de sector) şi fiecare sector cache conŃine un câmp tag
pentru a identifica adresa sectorului din MP actualizat în acest sector cache. Transferurile
între MP şi cache nu sunt implementate la nivel de sector; unitatea transferabilă este linia şi
liniile sunt transferate pe măsură ce sunt revendicate de către procesor. În cazul unui miss în
cache (miss la nivel de sector deoarece tag-ul este la nivel de sector), linia solicitată se
transferă din MP în locaŃia sa specifică din cadrul sectorului cache. Sectorul în cache este
selectat pe baza algoritmului de înlocuire (evacuare). O dată cu încărcarea liniei în sectorul
cache respectiv se va actualiza şi câmpul tag asociat sectorului respectiv astfel încât
celelalte linii existente în sectorul respectiv vor fi moştenite din sectorul anterior. Pentru a
diferenŃia noua linie (noile linii) care aparŃine cu adevărat sectorului identificat de câmpul
tag, de vechile linii moştenite din sectorul anterior, fiecare linie va avea asociat un bit de
validare. Când o linie ce aparŃine unui sector nou este încărcată în cache, odată cu
actualizarea câmpului tag, se setează şi bitul de validare asociat noii linii şi toate celelalte
linii (vechi) vor fi invalidate (biŃii de validare resetaŃi). Următoarele accese la linii invalide
dar în acelaşi sector, vor cauza doar încărcarea liniilor respective în cache şi setarea biŃilor
de validare asociaŃi.

52
ARHITECTURA SISTEMELOR DE CALCUL

Să notăm că, deşi sectoarele pot fi plasate oriunde în cache, odată ce sectorul a fost
plasat într-o anumită poziŃie, liniile sale trebuie plasate în locaŃiile corespunzătoare din
cadrul sectorului (linia i va fi plasată în locaŃia i). Deci, câmpul line din adresă acŃionează
ca un index în cadrul sectorului; algoritmul de înlocuire va lua în considerare doar adresele
de sector.
Organizarea în sectoare a fost utilizată în primul sistem comercial dotat cu
memorie cache: IBM 360 - model 85. Cache-ul acestui sistem avea 16 sectoare şi fiecare
sector avea 16 linii. Fiecare linie avea 64 octeŃi rezultând 1024 octeŃi în fiecare sector şi un
cache cu capacitatea de 16 KBytes. La miss 4 octeŃi erau transferaŃi din MP în cache şi
simultan în procesor. MP era organizată în 4 blocuri cu adresare întreŃesută. Algoritmul de
înlocuire utilizat era algoritmul LRU (Least Recently Used), funcŃiona la nivelul sectoarelor
şi era implementat în hardware.
Organizarea în sectoare poate fi privită ca o organizare complet asociativă cu biŃi
de validare. Fiecare linie din cache-ul complet asociativ corespunde unui sector, şi fiecare
octet ar corespunde unei linii. Deşi organizarea în sectoare a pierdut din popularitate după
IBM 360 - 85 (probabil datorită ratei de hit inferioare celei aferente organizării în seturi
asociative), o formă a organizării în sectoare a reapărut în sistemele cu microprocesoare.
Lărgimea limitată a busului în sistemele cu microprocesoare face imposibil transferul
simultan a unui număr mare de cuvinte.

3.3. Mecanismele de fetch şi scriere


3.3.1. Strategii de fetch

Se pot identifica 3 strategii de fetch (extragere) a octeŃilor din MP în cache:

1. fetch la cerere
2. prefetch
3. fetch selectiv

Fetch la cerere este strategia prin care o linie este extrasă din MP şi încărcată în
cache atunci când devine necesară (procesorul o accesează) şi nu se află deja în cache
(fetch-ul unei linii la miss). Această strategie este cea mai simplă şi nu necesită hardware
sau tag-uri adiŃionale în cache pentru a înregistra referinŃele la memorie, exceptând
hardware-ul de identificare a liniei cache ce va fi înlocuită.
Termenul de prefetch identifică strategia de extragere a liniilor din MP în cache înainte ca
acestea să fie solicitate. O strategie simplă de prefetch constă în prefetch-ul (fetch-ul
anticipat) liniei i + 1 când linia i este pentru prima dată referită (presupunând că linia i + 1
nu se află deja în cache), în baza presupunerii că este foarte probabil ca linia i + 1 să
urmeze a fi referită din moment ce linia i este referită. Această strategie de prefetch
secvenŃial poate reduce rata de miss cu 50 % dacă se implementează într-un cache suficient
de mare. Inevitabil, prefetch-ul liniei i + 1 înseamnă înlocuirea altei linii din cache, şi în
anumite cazuri chiar linia înlocuită ar urma să fie referită şi nu linia i + 1. Este însă clar că,
şi în cazul acestei simple strategii de prefetch secvenŃial, nu toate primele referinŃe vor

53
Memorii cache

induce miss deoarece multe vor referi linii încărcate anticipat în cache (secvenŃialitatea
instrucŃiunilor în program). Prefetch-ul ar putea fi limitat la situaŃiile în care fetch-ul liniei i
se face cu miss (prefetch la miss).
Fetch-ul selectiv descrie tehnica de condiŃionare a fetch-ului liniilor din MP în
cache. Fetch-ul se va executa pe baza unui criteriu definit, şi criteriul va defini situaŃii în
care MP va fi desemnată să reŃină anumite informaŃii şi nu memoria cache. De exemplu,
datele read/write partajate ar putea fi mai uşor de gestionat dacă sunt menŃinute permanent
în MP şi nu transferate în cache (în special în sistemele multiprocesor). În acest caz cache-
ul trebuie astfel proiectat încât procesorul să poată accesa MP direct, şuntând cache-ul.
Anumite locaŃii ar putea fi definite astfel non-cache-abile.

3.3.2. Cache-uri de instrucŃiuni şi cache-uri de date

În arhitecturile clasice (von Neumann) MP are sarcina de a memora atât


instrucŃiunile programului cât şi datele cu care acestea operează. Memoria cache poate fi
organizată în aceeaşi manieră astfel încât, în timpul execuŃiei unui program, în cache se vor
actualiza atât instrucŃiuni cât şi date. Acesta este cache-ul unificat. În arhitectura Harvard
MP este divizată în memorie pentru instrucŃiuni şi respectiv memorie pentru date,
organizare care conferă anumite avantaje în cazul procesării în tehnică pipeline (cap. 5).
Anumite avantaje apar şi la nivelul cache-ului dacă acesta este divizat în două părŃi, o parte
care conŃine datele (cache-ul de date) şi o parte care conŃine instrucŃiunile programului
(cache-ul de instrucŃiuni). Primul avantaj ar fi că strategiile de scriere în cache trebuie
implementate doar la nivelul cache-ului de date (considerând că instrucŃiunile nu sunt
modificate în timpul execuŃiei programului). Al doilea avantaj ar fi că se pot prevedea
busuri separate între procesor şi cele 2 cache-uri ceea ce va permite transferuri simultane
între procesor şi cache-ul de date şi respectiv între procesor şi cache-ul de instrucŃiuni.
Posibilitatea execuŃiei simultane a celor două transferuri este foarte convenabilă pentru
procesoarele pipeline (cap. 5) deoarece module pipeline diferite vor putea accesa simultan
ambele cache-uri (în timp ce unitatea de instrucŃiuni (IF) va accesa cache-ul de instrucŃiuni,
unitatea de memorare a rezultatului (SR) va accesa cache-ul de date). Al treilea avantaj ar fi
că cele 2 cache-uri pot fi de capacităŃi diferite, pot avea organizări interne diferite şi liniile
cache pot fi de dimensiuni diferite. Structura de principiu a unui sistem cu cache-uri
separate pentru instrucŃiuni şi date este prezentată în fig. 3.8.
Cache-ul divizat este implementat cel mai adesea în interiorul procesorului (cache intern).
Multe microprocesoare au cache-uri interne separate, de exemplu Intel Pentium (nu şi Intel
486) şi Motorola MC 68040.
Cache-urile separate introduc anumite complicaŃii şi constrângeri în special dacă
se introduc la anumite microprocesoare membre ale unor familii de procesoare (când se
pune şi problema compatibilităŃii cu procesoarele anterioare din cadrul aceleiaşi familii).
Cele mai multe procesoare mai permit încă programatorului să scrie şi compilatorului să
genereze cod automodificabil (cod care se automodifică), chiar dacă se încearcă
descurajarea severă a acestor acŃiuni.

54
ARHITECTURA SISTEMELOR DE CALCUL

Memorie Principală
(MP)

Cache de Cache de În general în


instrucŃiuni date interiorul procesorului
(cache-uri interne)

InstrucŃiuni Date

Unitatea fetch Unitatea de acces


instrucŃiune (IF) la memorie

Procesor Pipeline-ul de instrucŃiuni

Fig. 3.8. Cache-uri separate de instrucŃiuni şi respectiv de date

Dacă automodificarea este permisă vor apărea probleme cu instrucŃiunile memorate atât în
cache-ul de instrucŃiuni cât şi în cel de date. Dacă instrucŃiunea se modifică în cache-ul de
date, copia sa din cache-ul de instrucŃiuni va rămâne diferită. De asemenea, momentul în
care modificarea survine depinde de structura pipeline specifică a procesorului şi
modificarea nu este posibilă înainte de fetch-ul instrucŃiunii vizate (ce va fi modificată).
Foarte multe procesoare permit de asemenea încărcarea instrucŃiunilor şi a datelor în locaŃii
de memorie consecutive sau învecinate, astfel încât devine posibil ca o linie cache să
conŃină atât instrucŃiuni cât şi date. Din nou vom avea 2 copii ale aceleiaşi linii în cache-uri
separate, şi deci o problemă cu consistenŃa celor 2 copii. Desigur toate aceste probleme pot
fi eliminate dacă se insistă ca instrucŃiunile şi datele să fie separate în memorie (aşa cum ar
fi normal să fie) şi dacă se interzice scrierea de cod automodificabil. În caz contrar o soluŃie
ar fi să se invalideze linia din cache-ul de instrucŃiuni în momentul în care copia ei din
cache-ul de date este modificată (scrisă). Acest aranjament permite duplicarea unei linii în
ambele cache-uri dar numai până în momentul modificării copiei din cache-ul de date.

3.3.3. OperaŃiile de scriere

Dacă se iau în considerare doar operaŃiile de citire din memorie este evident că nu
pot să apară diferenŃe între cuvintele din MP şi copiile acestora din cache. Totuşi, în timpul

55
Memorii cache

execuŃiei unui program, se execută şi operaŃii de scriere (în cache) şi astfel devine posibil
ca cuvântul din cache şi copia sa din MP să devină diferite. Dacă transferurile de intrare-
ieşire din sistem (transferurile DMA - Direct Memory Acces - implementate pentru
perifericele rapide) operează cu conŃinutul MP, sau dacă mai multe procesoare operează cu
conŃinutul MP (ca în sistemele multiprocesor cu memorie partajată), este necesar ca
locaŃiile cache şi copiile acestora din MP să se menŃină identice.
Dacă se ignoră penalităŃile cauzate de operaŃiile suplimentare introduse pentru
menŃinerea consistenŃei copiilor, şi timpul necesar scrierii datelor înapoi în MP, atunci
timpul mediu de acces va fi dat de relaŃia (3.4) de la 3.1.3 (presupunând că toate accesele se
fac întâi în cache):

ta = tc + (1-h)·tm

OperaŃiile de scriere vor adăuga un timp adiŃional în ecuaŃia de mai sus, timp care depinde
de mecanismul utilizat pentru menŃinerea consistenŃei datelor. Dacă nu este necesar să se
menŃină consistente conŃinutul cache-ului şi conŃinutul MP (de exemplu în sistemele în care
toate procesoarele şi toate controllere-le I/E accesează datele în cache), atunci timpul
mediu de acces va fi dat de relaŃia de mai sus.
Deşi timpul mediu de acces în cache reprezintă un factor care determină în mod
esenŃial performanŃele globale ale sistemului şi din această cauză îl vom evalua pentru
diverse strategii de scriere/citire, viteza globală de procesare este influenŃată şi de alŃi
factori. În particular, viteza de execuŃie a instrucŃiunii este determinată de diversele operaŃii
interne CPU (Central Processing Unit) la care se adaugă operaŃiile de fetch instrucŃiune şi
accesele la operanzi. De asemenea, arhitectura maşinii poate influenŃa profund
performanŃele globale. O simplă creştere a lungimii liniei cache fără o extindere (lărgire)
adecvată a busului de date MP - cache poate conduce la diminuarea performanŃelor globale
deoarece copierea unei linii din MP în cache revendică transferuri multiple pe busul
respectiv.
Există două mecanisme alternative de actualizare a conŃinutului MP în cadrul
operaŃiilor de scriere:
− mecanismul write-through
− mecanismul write-back (numit uneori copyback)

3.3.4. Mecanismul write-through

În mecanismul write-through, orice operaŃie de scriere în cache este repetată şi în


MP, de regulă în acelaşi timp, asigurând astfel consistenŃa datelor. OperaŃia adiŃională de
scriere în MP va consuma mult mai mult timp decât scrierea în cache şi va domina timpul
de acces aferent operaŃiilor de scriere. Din fericire, numărul de operaŃii de scriere (în timpul
execuŃiei unui program) este semnificativ mai mic în comparaŃie cu numărul de operaŃii de
citire (tipic apar 3-10 citiri la o scriere). Timpul mediu de acces în cazul write-through cu
transferuri din MP în cache la fiecare miss (miss la citire şi miss la scriere) este dat de:

56
ARHITECTURA SISTEMELOR DE CALCUL

ta = tc + (1-h)·tl + w·(tm - tc) (3.10)

unde:
tl - timpul de transfer a unei linii în cache (considerând că la miss întreaga linie
trebuie transferată)
w - procentul de referinŃe la memorie cu write (numărul de scrieri raportat la
numărul total de referinŃe la memorie)

Termenul (tm - tc) reprezintă timpul adiŃional indus de scrierea unui cuvânt în MP
(la hit sau miss), considerând că operaŃiile de scriere în cache şi respectiv MP se derulează
simultan şi că operaŃia de scriere trebuie să se încheie (inclusiv în MP) înaintea startării
următoarei operaŃii read/write în cache. Dacă lungimea liniei este identică cu lăŃimea
busului de date MP - cache atunci o linie completă va putea fi transferată într-o singură
tranzacŃie pe bus şi tl = tm. Dacă linia este mai lungă decât lăŃimea busului de date extern
atunci tl = l·tm unde l reprezintă numărul de tranzacŃii pe bus necesare pentru transferul unei
linii complete.
Presupunând tc = 25 ns, tm = 200 ns, h = 99 %, w = 20 % şi lungimea liniei cache
egală cu lăŃimea busului extern (l = 1), timpul mediu de acces va fi 62 ns, din care 2 ns se
datorează ciclurilor miss şi 35 ns se datorează scrierilor în tehnica write-through. Când
lăŃimea busului extern este mai mică decât lungimea liniei cache, vor fi necesare mai multe
tranzacŃii pe bus pentru transferul unei linii şi penalităŃile cauzate de ciclurile miss devin
mai semnificative. De exemplu, dacă l = 16 (linia de 16 ori mai lungă decât lăŃimea busului
extern), timpul mediu de acces devine 92 ns, din care 32 ns se datorează ciclurilor miss şi
35 ns se datorează scrierilor în tehnica write-through.
În cazul unui ciclu miss, linia ar putea fi transferată din MP în cache indiferent
dacă ciclul miss a fost cauzat de o operaŃie de scriere sau de una de citire. Termenul fetch
on write este utilizat pentru a descrie strategia de aducere a liniei/cuvântului din MP în
cache în cazul operaŃiilor de scriere cu miss. În strategia write-through, transferurile fetch
on write sunt cel mai adesea evitate (se aplică strategia no fetch on write în care informaŃia
este scrisă doar în MP). Termenul allocate on write este uneori utilizat pentru a descrie
strategia fetch on write deoarece o linie cache este alocată unei linii noi în caz de miss în
cache. Termenul non-allocate on write se asociază uneori strategiei no fetch on write.
Timpul mediu de acces în cazul strategiei no fetch on write va fi:

ta = tc + (1-w)·(1-h)·tl + w·(tm - tc) = (1-w)·[ tc + (1-h)·tl] + w·tm (3.11)

Să notăm că atunci când se utilizează teoria probabilităŃilor trebuie luate în


considerare toate combinaŃiile. RelaŃia (3.11) poate fi dedusă şi prin luarea în considerare a
tuturor combinaŃiilor posibile (read/write cu hit/miss):

ta = (1-w)·h·tc + (1-w)·(1-h)·(tc + tl) + w·h·tm + w·(1-h)·tm (3.12)


Read-hit Read-miss Write-hit Write-miss

57
Memorii cache

Rata de hit va fi uşor mai mică decât în cazul strategiei fetch on write deoarece
liniile alterate prin scriere în MP nu mai sunt aduse în cache şi, în funcŃie de program, ar
putea fi din nou accesate prin operaŃii de citire ulterioare. Presupunând că rata de hit şi
ceilalŃi parametrii au aceleaşi valori ca în exemplul anterior, timpul mediu de acces în cazul
strategiei no fetch on write (relaŃia 3.11) va fi 61,6 ns, pentru l = 1, şi respectiv 85,6 ns,
pentru l = 16.
Mecanismul write-through poate fi îmbunătăŃit prin introducerea unor buffer-e, ca
în fig. 3.9, pentru reŃinerea informaŃiilor ce urmează a fi scrise înapoi în MP, eliberând
cache-ul pentru următoarele accese. Astfel de buffer-e apar şi în cazul strategiei write-back
(secŃiunea 3.3.5). În cazul strategiei write-through, fiecare cuvânt ce trebuie scris înapoi în
MP va fi plasat în buffer împreună cu adresa locaŃiei MP în care va fi memorat (dacă
transferul nu poate fi executat imediat). O capacitate de 4 locaŃii pentru write-buffer este în
general suficientă (Intel 486 utilizează strategia write-through şi un buffer de 4 locaŃii).
Dacă operaŃiile write-through devin total transparente, atunci timpul mediu de acces va fi
dat de relaŃiile stabilite în secŃiunea 3.1.3). Buffer-ul de scriere revendică o logică de control
complexă care trebuie să asigure verificarea conŃinutului său la orice acces la MP iniŃiat de
către procesor/cache sau un alt dispozitiv. Toate adresele cu care se accesează MP trebuie
comparate cu adresele memorate în buffer.

Date Memoria Principală


Procesor Adresă
Cache
Write

Read

Fig. 3.9. Cache cu buffer de scriere (write-buffer)

Strategia de a scrie imediat în MP noile valori asigură actualizarea MP cu cele mai


recente valori şi deci orice dispozitiv sau procesor care accesează MP ar trebui să obŃină
imediat cele mai recente valori; se evită astfel necesitatea implementării unor mecanisme
complicate pentru menŃinerea consistenŃei conŃinutului MP. Va exista totuşi o latenŃă în
procesul de actualizare a conŃinutului MP, şi conŃinuturile cache-ului şi MP sunt
neconsistente pe durata acestei perioade. Dacă procesorul întâlneşte o condiŃie de eroare,
sistemul va putea fi restaurat relativ uşor (în cazul utilizării strategiei write-through); MP
conŃine de regulă circuite de detecŃie şi corecŃie a erorilor bazate pe biŃi de paritate sau
coduri Hamming, în timp ce memoria cache nu deŃine întotdeauna astfel de circuite.
Strategia write-through este foarte răspândită; ea poate fi remarcată în multe
sisteme cu microprocesoare, fiind foarte uşor de implementat şi gestionat în sistemele
unibus. Totuşi, orice operaŃie de scriere va genera un transfer în MP, şi deci un acces pe

58
ARHITECTURA SISTEMELOR DE CALCUL

unibus. Această creştere a traficului pe unibus devine semnificativă dacă busul este accesat
şi de alte dispozitive sau procesoare aşa cum se întâmplă în sistemele multiprocesor.

3.3.5. Mecanismul write-back

În mecanismul write-back, scrierea în cache şi respectiv în MP nu se face


simultan. Scrierea unei linii în MP se amână până în momentul înlocuirii liniei respective în
cache; în acest moment linia ce urmează a fi înlocuită cu o linie nouă, va fi scrisă înapoi în
MP indiferent dacă această linie a fost alterată în cache sau nu. Această strategie se
numeşte strategie write-back simplă şi conduce la un timp mediu de acces de forma:

ta = tc + (1-h)·tl + (1-h)·tl = tc + 2·(1-h)·tl (3.13)

unde primul termen (1-h)·tl se datorează operaŃiilor de fetch linie din MP în cache iar al
doilea termen (1-h)·tl se datorează operaŃiilor write-back în MP. Mecanismul write-back în
general aplică strategia fetch on write în cazul ciclurilor de scriere cu miss, spre deosebire
de mecanismul write-through care aplică de regulă strategia no fetch on write.
Un mecanism write-back îmbunătăŃit scrie înapoi în MP doar liniile care au fost
alterate (modificate) în cache (liniile nealterate nu mai trebuie scrise înapoi în MP deoarece
copia din MP este încă identică cu cea din cache). Pentru a implementa această strategie un
bit suplimentar (A-altered) va fi asociat fiecărei linii în cache şi acest bit va fi setat ori de
câte ori se face scriere în linia cache respectivă. În momentul înlocuirii, bitul A este
examinat pentru a determina dacă linia respectivă trebuie scrisă sau nu înapoi în MP. În
această situaŃie timpul mediu de acces devine:

ta = tc + (1-h)·tl + wl·(1-h)·tl = tc + (1-h)·(1+wl)·tl (3.14)

unde wl reprezintă probabilitatea ca o linie cache să fie alterată (procentul de linii alterate).
Probabilitatea ca o linie să fie alterată (wl) are ca limită maximă valoarea w (probabilitatea
ca o referinŃă la memorie să fie scriere sau, altfel spus, procentul de accese cu scriere din
totalul acceselor la memorie). Este foarte probabil ca wl să ia valori mult mai mici decât w
deoarece, până în momentul write-back, este foarte probabilă execuŃia mai multor operaŃii
de scriere în aceeaşi linie cache. Rata de hit este aceeaşi ca şi în cazul strategiilor write-
back simplă şi respectiv write-through cu fetch on write dar ta se reduce chiar semnificativ
(cu (1-h)·(1-wl)·tl faŃă de strategia write-back simplă). Totuşi, şi această strategie, în
momentul write-back scrie o linie completă în MP, chiar dacă în linia respectivă a fost
alterat doar un singur cuvânt. Cuvintele nealterate care se transferă necondiŃionat vor crea
un trafic suplimentar (nenecesar) pe bus şi acest trafic suplimentar creşte dacă lăŃimea
busului MP - cache este mai mică decât lungimea liniei cache. Chiar şi în aceste condiŃii
strategia write-back va provoca un trafic mai redus decât strategia write-through care
determină transferul în MP a fiecărei linii cache în momentul alterării ei. Strategia write-
back poate fi îmbunătăŃită (ca şi strategia write-through) prin introducerea unor buffer-e
(fig. 3.9) pentru reŃinerea informaŃiei ce urmează a fi transferată înapoi în MP.

59

S-ar putea să vă placă și