Perioada 1993-1998 a fost foarte zbuciumata, marcata de o lupta foarte dura
pe piata microprocesoarelor, in care Intel a inceput sa simta din ce in ce mai
mult prezenta competitiei formate din AMD, Cyrix sau NexGen. Tot in aceasta
perioada s-a lansat si standardul MMX care mai este folosit si in prezent.
Era Pentium (1993-1998)
Intel Pentium (22 martie 1993) q8m20mn
Intel Pentium a fost primul procesor superscalar de la Intel (putea executa
pana la doua instructiuni simultan). Multi s-au intrebat de ce Intel nu a denumit
acest procesor 80586. Motivul a fost ca numele format numai din cifre nu putea
fi protejat de copyright, asa ca Intel s-a vazut nevoit sa foloseasca si litere
pentru a-si diferentia produsele de cele ale concurentei. Procesorul lucra cu
o magistrala de date de 64 de biti (cu toate ca a fost un procesor pe 32 de
biti) si a fost lansat initial la viteze de 60 si 66 de MHz. Au urmat insa foarte
rapid versiuni de 75, 90, 100, 120, 133, 150, 166, 200, 233 MHZ. De fapt au
existat trei versiuni de Pentium: prima versiune care nu cuprindea decat doua
modele: Pentium la 60 si la 66MHz, a doua versiune care a adaugat instructiunile
MMX si o ultima versiune care a micsorat distanta dintre tranzistoare permitand
astfel viteze mai mari care au ajuns pana la 233MHz. Intel Pentium a fost primul
microprocesor pentru PC-uri care putea sa calculeze mai mult de 100MIPS (milioane
de instructiuni pe secunda). Tot pentru prima oara era posibila construirea
unor sisteme care sa lucreze cu 2 procesoare in paralel (sisteme multiprocesor).
Microprocesorul de la Intel venea cu 16Kb de cache incorporati in pastila de
siliciu.
AMD K5 / Nexgen Nx586 (1995)
AMD a reactionat destul de tarziu in a lansa un procesor comparabil ca viteza
cu Intel Pentium. In 1995 a produs totusi primul sau procesor care era conceput
integral de catre ei, nemaifiind o simpla clona a procesoarelor Intel. Acest
procesor s-a numit K5 si avea viteze de la 75 la 166MHz. Cu toate acestea nu
era un procesor mai rapid decat cele de la Intel, in plus avand o unitate de
calcul in virgula mobila destul de slaba (ca si Cyrix de altfel). Una din inovatiile
aduse de K5 era faptul ca instructiunile x86 erau transformate intern in ROP
(Risc OPerations). Aceste operatii RISC se puteau executa in nucleul RISC al
procesorului care era mult mai rapud. In acelasi timp o companie de care putina
lume auzise pana atunci, Nexgen, lansa primul sau procesor: Nx586. Complexitatea
procesorului K5 a dus la frecvente destul de mici, ceea ce i-a facut pe cei
de la AMD sa cumpere compania Nexgen care tocmai terminase design-ul noului
lor procesor, NX686. Acest design a fost ulterior folosit de AMD in urmatoarea
sa familie de procesoare pe care avea sa o lanseze in 1997.
Cyrix 6x86 (Octombrie 1995)
6x86 a fost replica lui Cyrix la procesorul Pentium al lui Intel. Acest chip
era produs initial de catre IBM dat fiind ca Cyrix nu avea unitati de asamblare
de procesoare, insa ulterior, odata cu achizitionarea Cyrix de catre National
Semiconductor a fost produs chiar de catre acestia. Procesorul a avut un succes
destul de mare dat fiind ca era mai rapid decat un Intel Pentium la aceeasi
frecventa. De altfel pentru a-l putea compara cu procesoarele de la Intel, cei
de la Cyrix au inventat ceea ce s-a numit ulterior P-Rating. De exemplu procesorul
Cyrix 6x86 care functiona la 150 de MHz a fost denumit 6x86PR200, ceea ce insemna
ca era comparabil ca viteza cu un Pentium la 200. Unul din marile dezavantaje
ale acestui procesor a fost insa viteza foarte mica a calculelor in virgula
mobila. Cu toate acestea in aplicatiile de tip office s-a dovedit cel putin
la fel de rapid ca si un Pentium.
Intel Pentium Pro (1 noiembrie 1995)
Acest procesor a fost una dintre cele mai mari inovatii tehnice produse de Intel
pana acum. Procesorul ingloba pentru prima oara in istorie pe langa cache-ul
Level1 de 8k pentru date si 8k pentru instructiuni, si un cache Level2 de 256Kb
sau 512Kb. Folosea un sistem complex de predictie a ramurii de executie (branch
prediction) si executie speculativa (speculative execution) - in momentul in
care executia programului ajungea la o bifurcatie ramura corecta nu era stiuta
pana in momentul in care se executa instructiunea conditionala; pentru ca procesorul
sa nu astepte pana in acea clipa, se alegea una din cele doua ramuri si se incepea
executia instructiunilor respective; daca se dovedea ca ramura aleasa a fost
cea corecta aceasta insemna un castig important de viteza. Acest microprocesor
transforma instructiunile x86 in microoperatii care erau mult mai mici si mai
rapide. Acest lucru, cu toate ca avea ca rezultat o viteza mult mai mare a instructiunilor
de 32 de biti, a dus la performante mult mai slabe in sistemele de operare care
mai contineau cod pe 16 biti. Acesta a fost unul din motivele performantei mai
mici comparabil cu Intel Pentium in Windows 95 de exemplu.
Intel Pentium MMX (Ianuarie 1997)
MMX s-a crezut initial ca inseamna MultiMedia eXtension, dar Intel a declarat
ca inseamna Matrix Math eXtension. Acesta reprezinta un standard introdus de
Intel care aduce cateva noi instructiuni care usurau in principal calculele
matematice cu vectori.
AMD K6 (Aprilie 1997)
Ca urmare a cumpararii firmei Nexgen, AMD a reusit sa lanseze un nou procesor,
K6 care avea viteze de la 166 la 266MHz. Bineinteles ca politica AMD a fost
ca procesoarele sale sa se vanda la aproape jumatate din pretul la care se vindeau
procesoarele Intel. K6 incorpora instructiuni MMX (a caror licenta a cumparat-o
de la Intel) devenind astfel un rival de temut pentru procesoarele Intel Pentium
MMX.
Cyrix 6x86MX (30 Mai 1997)
6x86MX a adus nou extensiile MMX precum si viteze de ceas mai mari decat precedentele
chip-uri de la Cyrix. Astfel cel mai performant model era 6x86MX PR266 care
rula la 233MHz. De asemenea, marimea memoriei cache Level2 s-a marit de patru
ori fata de 6x86, ajungand la 64Kb.
Cyrix MII (14 Aprilie 1998)
Aceasta versiune a chip-ului 6x86 a imbunatatit putin performanta FPU si a atins
viteze mai mari ajungand la 300MHz (PR433). De asemenea viteza bus-ului a ajuns
la 100MHz.
Cyrix MediaGX (1998)
MediaGX a reprezentat incercarea lui Cyrix de a produce un chip care sa integreze
atat functiile de sunet si video, cat si controller-ul de memorie si CPU-ul
in sine. Scopul acestui chip a fost acela de a putea produce computere foarte
ieftine si la vremea aceea deja se vorbea de calculatoare sub 500$ (ceea ce
era foarte putin la acea data) construite in jurul lui MediaGX. Cu toate acestea,
nici unul din marii producatori de computere nu a adoptat aceasta solutie, astfel
incat procesorul acesta, desi revolutionar, nu a avut deloc succesul scontat.
Procesoarele Cyrix
Arhitectura x86
Corporatia Cyrix este unul dintre furnizorii de baza ai solutiilor bazate pe
microprocesoare, care a introdus noi standarde pe piata calculatoarelor personale.
In ultimii zece ani Cyrix a dezvoltat aproape o duzina de procesoare originale
folosite in milioane de calculatoare din intreaga lume.
In luna noiembrie a anului 1997, Cyrix a fost cumparata de National Semiconductor.
Aceasta fuziune a adus doua componente importante pentru Cyrix: capacitatea
de productie la nivel mondial a National Semiconductor si infrastructura necesara
acestei productii.
Primul produs Cyrix a fost un coprocesor matematic destinat cresterii vitezei
de realizare a calculelor matematice. Succesul acestui coprocesor matematic
a permis celor de la Cyrix sa distribuie incepand cu 1992, primul
procesor din familia x86. Compania a dezvoltat rapid o linie de productie pentru
procesoarele 486, si apoi pentru procesoarele din generatia a cincea 5x86, un
CPU pentru sistemele PC (mobile si desktop). In 1995, Cyrix a introdus
procesorul din generatia a sasea, 6x86, un procesor superscalar, bazat pe o
superbanda de asamblare; in iunie 1997, a introdus procesorul MMX 6x86MX,
iar in 1998 a aparut procesorul MII.
Procesorul Cyrix 5x86
Familia de procesoare 5x86 reprezinta o noua generatie pe 64 de biti compatibila
x86. Unitatea centrala se bazeaza pe o banda de asamblare cu sase nivele, putand
executa o instructiune intr-un impuls de tact.
Unitatea centrala 5x86 este divizata in urmatoarele blocuri functionale
(Fig. 1): -unitatea pentru numere intregi (Integer Unit - IU), -unitatea
in virgula flotanta (Floating Point Unit - FPU) , -unitatea cache (Write-Back
Cache) , -unitatea pentru gestiunea memoriei (Memory Management Unit - MMU)
, -unitatea de interfata cu magistrala (Bus Interface Unit - BIU).
Unitatea pentru numere intregi contine: -tamponul pentru instructiuni
(Instruction Buffer - IB) , -unitatea de aducere a instructiunii (Instruction
Fetch Unit - IF) , -unitatea de decodificare a instructiunii (Instruction Decoder
Unit - ID).
Instructiunile sunt executate in unitatea pentru numere intregi
sau in unitatea de calcul in virgula flotanta. Cache-ul contine
cele mai recent utilizate date si instructiuni si asigura accesul rapid la aceste
date din partea IU si FPU.
Cand apare o cerere de acces la o locatie din memoria externa, MMU calculeaza
adresa fizica pe care o trimite unitatii de interfata cu magistrala, care asigura
interfatarea unitatii centrale cu memoria externa si celelalte circuite de pe
placa de baza.
Unitatea pentru numere intregi
Aceasta unitate citeste, decodifica si executa intructiunile intr-o banda
de asamblare cu sase nivele (Fig. 2): -nivelul de aducere al codului instructiunii
(Instruction Fetch - IF) - citeste din cache codul instructiunii urmatoare si
il trimite spre decodificare nivelului urmator din banda de asamblare.
Se pot citi pana la 128 de octeti intr-un impuls de tact, -nivelul
de decodificare a instructiunii (Instruction Decode - ID) - evalueaza sirul
de octeti primit de la nivelul IF, determinand numarul de octeti pentru
fiecare instructiune si tipul acesteia, pe care apoi le decodifica la viteza
de o instructiune intr-un impuls de tact, -primul nivel de caclul al adresei
(Address Calculation 1 - AC1) - daca instructiunea are un operand in memorie,
acest nivel calculeaza adresa de memorie liniara pentru instructiune, -al doilea
nivel de caclul al adresei (Address Calculation 2 - AC2) - realizeaza toate
functiile de gestionare a memoriei, accesarea cache-ului si a registrelor. Daca
detecteaza o instructiune in virgula flotanta, aceasta este trimisa pentru
executie unitatii in virgula flotanta, -nivelul de executie (Execution
- EX) - executa instructiunea folosind operanzii furnizati de nivelele pentru
calculul adresei, -nivelul write-back (WB) - ultimul nivel din IU, actualizeaza
setul de registre sau trimite rezultatul unitatii de interfata cu memoria (Load/Store
Unit) din MMU.
Unitatea cache
Procesorul Cyrix 5x86 contine un cache unificat pentru date si instructiuni
de 16Ko, set-asociativ pe patru cai, organizat pe 1024 de linii. Scrierile in
cache se fac prin metoda write-back. Memoria cache este organizata in
patru bancuri a cate 256 linii fiecare, cu 16 octeti pe linie. Fiecare
linie cache are asociat cate un tag pe 21 de biti si un bit de valid (arata
daca linia contine informatii valide sau nu). Pe langa acesti biti, fiecare
linie mai contine inca patru biti care indica daca continutul liniei a
fost modificat (dirty bits), cate unul pentru fiecare dublu-cuvant
din linie. Acesti ultimi patru biti permit marcarea independenta a fiecarui
dublu-cuvant ca fiind modificat, in loc de a marca intreaga
linie ca fiind modificata.
Unitatea de gestionare a memoriei
MMU translateaza adresele liniare furnizate de IU in adrese fizice, pentru
a putea fi folosite de unitatea cache si unitatea de interfata cu magistrala.
Mecanismul de paginare este cel standard x86.
Unitatea pentru gestionarea memoriei mai contine un bloc (Load/Store Unit) care
planifica accesele la memoria cache si memoria externa si implementeaza urmatoarele
concepte: -reordonarea citirilor si scrierilor - confera o prioritate mai mare
citirilor din memorie fata de scrierile in memorie, -evitarea citirilor
din memorie - elimina citirile inutile din memorie prin folosirea datelor existente
deja in unitatea centrala (in cazul dependentelor de tipul citire
dupa scriere).
Controlul ramificatiilor, prezicerea ramificatiilor, dependentele intre
date, unitatea in virgula flotanta, unitatea de interfata cu magistrala
vor fi prezentate la procesorul 6x86.
Procesorul Cyrix 6x86
Procesorul Cyrix 6x86 este cel mai performant dintre procesoarele de generatia
a sasea compatibile x86. Imbunatatirea performantelor este realizata prin
utilizarea unei arhitecturi superscalare, bazate pe o superbanda de asamblare.
Cyrix 6x86 este un procesor superscalar, deoarece contine doua benzi de asamblare
separate ce permit procesarea mai multor instructiuni in acelasi timp.
Folosirea unei tehnologii de procesare avansate si cresterea numarului de nivele
in benzile de asamblare (superpipelining) permit procesorului 6x86 sa
atinga frecvente de lucru mai mari de 100MHz.
Prin folosirea caracteristicilor arhitecturale unice, procesorul 6x86 elimina
multe dintre dependentele intre date si conflictele la accesarea resurselor,
rezultand o performanta optima atat pentru programele pe 16 biti
cat si pentru cele pe 32 de biti.
Procesorul Cyrix 6x86 contine doua cache-uri: -un cache unificat (pentru date
si pentru instructiuni) de 16Ko dual port, si -un cache de instructiuni de 256
octeti.
Deoarece cache-ul unificat poate contine instructiuni si date in orice
raport, acesta ofera o rata a hit-urilor (numarul de accese in cache,
raportat la numarul total de accese) mai mare comparativ cu doua cache-uri separate
pentru date si pentru instructiuni, avand dimensiuni egale. O crestere
a latimii de banda a transferurilor cache-unitatea intreaga este realizata
prin suplimentarea cache-ului unificat cu un mic cache de instructiuni foarte
rapid, complet asociativ. Prin includerea acestui cache de instructiuni, se
evita conflictele excesive intre accesele pentru date si pentru cod in
cache-ul unificat.
Unitatea in virgula flotanta din procesor permite executarea instructiunilor
in virgula flotanta in paralel cu instructiunile intregi.
Aceasta contine o coada de instructiuni pe patru nivele si o coada pentru datele
scrise tot pe patru nivele, pentru a facilita executia paralela.
Procesorul 6x86 este alimentat la 3.3V ducand la un consum redus pentru
toate frecventele de lucru. In plus, 6x86 mai poseda un mod de suspendare
pe nivel scazut, posibilitatea de a intrerupe tactul si modul de management
al sistemului (SMM) pentru aplicatiile sensibile la alimentare.
Principalele blocuri funtionale
Procesorul Cyrix 6x86 contine cinci mari blocuri functionale (Fig. 3): -Unitatea
intreaga (Integer Unit - IU) , -Unitatea cache (Cache Unit) , -Unitatea
de gestionare a memoriei (Memory Management Unit - MMU) , -Unitatea in
virgula flotanta (Floating Point Unit - FPU) , -Unitatea de interfata cu magistrala
(Bus Interface Unit - BIU).
Instructiunile sunt executate in cele doua benzi de asamblare intregi
(X si Y) si in unitatea in virgula flotanta. Cache-ul contine cele
mai recent utilizate date si instructiuni pentru a permite accese rapide la
informatii din partea IU si FPU.
Adresele fizice sunt calculate de MMU si sunt trimise unitatii cache si unitatii
de interfata cu magistrala. BIU ofera o interfata intre placa sistem externa
si unitatile interne ale procesorului.
Unitatea intreaga
Unitatea de calcul cu numere intregi ofera o executie paralela a instructiunilor
in doua benzi de asamblare pentru numere intregi cu sapte nivele
(Fig. 4). Fiecare din cele doua benzi de asamblare (X si Y) poate procesa simultan
cateva instructiuni.
Benzile de asamblare intregi contin urmatoarele nivele de prelucrare:
-aducerea codului instructiunii (Instruction Fetch ?IF) , -primul decodificator
pentru instructiuni (Instruction Decode 1 ? ID1) , -al doilea decodificator
pentru instructiuni (Instruction Decode 2 ? ID2) , -primul bloc de calculare
a adresei (Address Calculation 1 ? AC1) , -al doilea bloc de calculare a adresei
(Address Calculation 2 ? AC2) , -executie (Execute ? EX) , -writeback (WB) (Fig.
4).
Nivelul de aducere al codului instructiunii (IF) este impartit de cele
doua benzi de asamblare, aduce cate 16 octeti de cod din unitatea cache
intr-un singur ciclu de tact. In acest nivel se cauta orice instructiune
de salt ce poate apare in fluxul de cod si poate afecta secventierea normala
a programului. Daca este detectata o instructiune de salt neconditionat sau
una de salt conditionat, logica de prezicere a salturilor din acest nivel genereaza
o posibila adresa destinatie pentru instructiunea de salt. Apoi IF aduce codul
instructiunilor incepand cu aceasta adresa.
Functia de decodificare a codului instructiunii este realizata de nivelele ID1
si ID2. Nivelul ID1, folosit de ambele benzi de asamblare, evalueaza sirul de
octeti de cod transmis de nivelul IF si determina numarul de octeti pentru fiecare
instructiune. Acest nivel poate trimite cel mult doua instructiuni intr-un
impuls de tact nivelului ID2, cate una pentru fiecare banda de asamblare.
Cele doua nivele ID2 decodifica instructiunile si le trimite uneia din cele
doua benzi de asamblare X sau Y spre executie. Banda de asamblare este aleasa
bazata pe tipul instructiunilor aflate deja in fiecare banda si cat
de repede se presupune ca se vor termina.
Functia de calculare a adreselor este realizata tot in doua nivele: AC1
si AC2. Daca instructiunea are o referinta la un operand in memorie, AC1
calculeaza o adresa de memorie liniara pentru instructiune.
Nivelul AC2 realizeaza toate functiile de gestiunea memoriei cerute, accesele
la cache si accesele la setul de registre. Daca AC2 detecteaza o instructiune
in virgula flotanta, aceasta este trimisa spre prelucrare unitatii FPU.
In nivelul de executie (EX), se executa instructiunile folosind operanzii
primiti din nivelul AC2.
Nivelul writeback (WB) este ultimul din unitatea de lucru cu numere intregi.
In acest nivel sunt stocate rezultatele executiei sau in registre
sau in tamponul de scriere din unitatea cache.
Procesarea in inordine
Daca o instructiune este executata mai repede decat instructiunea precedenta
din cealalta banda de asamblare, instructiunile sunt completate in inordine.
Toate instructiunile sunt prelucrate in ordine pana la nivelul EX.
In timp ce in nivelele EX si WB instructiunile pot fi executate
in inordine.
Daca exista dependente de date intre cele doua instructiuni, este necesara
interventia unui bloc care sa asigure executia corecta a programului. Astfel,
chiar daca instructiunile sunt executate in inordine, exceptiile si scrierile
din cadrul instructiunilor sunt intotdeauna efectuate in ordinea
ceruta de program.
Selectarea benzii de executie
In majoritatea cazurilor, instructiunile sunt prelucrate in oricare
din cele doua benzi de asamblare si nu exista constrangeri cu privire
la tipul instructiunilor executabile in paralel in cele doua benzi
de asamblare. Insa, unele instructiuni pot fi prelucrate doar de banda
de asamblare X: -instructiunile de salt, -instructiunile in virgula flotanta,
-instructiunile exclusive.
Instructiunile de salt si cele in virgula flotanta pot fi executate in
paralel cu o alta instructiune ce poate fi executata in banda Y. Instructiunile
exclusive nu pot fi executate in paralel cu nici o alta instructiune.
Aceste instructiuni necesita accese multiple la memorie. Chiar daca aceste instructiuni
sunt executate exclusiv, este folosit hardware-ul din cele doua benzi de asamblare
pentru a se accelera completarea instructiunii. In continuare sunt insirate
tipurile de instructiuni exclusive ale procesorului 6x86: -incarcarea
segmentelor in modul protejat, -accesele la registrele speciale (registrele
de control, debug si test) , -instructiunile pe siruri, -inmultirea si
impartirea, -accesele la porturile I/O, -PUSHA si POPA, -salturile intersegment,
apelurile de proceduri si iesirea din proceduri intersegment.
Solutionarea dependentelor de date
Cand doua instructiuni care sunt executate in paralel acceseaza
aceeasi data sau acelasi registru, poate apare una din urmatoarele tipuri de
dependente de date: -citire dupa scriere (Read-After-Write - RAW) , -scriere
dupa citire (Write-After-Read - WAR) , -scriere dupa scriere (Write-After-Write
- WAW).
Dependentele intre date in mod normal necesita serializarea executiei
instructiunilor implicate. Insa, 6x86 implementeaza urmatoarele trei mecanisme
ce permit executia paralela a instructiunilor ce contin dependente intre
date: -redenumirea registrelor (Register Renaming) , -inaintarea datelor
(Data Forwarding) , -evitarea datelor (Data Bypassing). In continuare,
se vor descrie pe scurt aceste meacnisme.
Redenumirea registrelor
Procesorul Cyrix 6x86 contine 32 registre fizice de uz general. Fiecare din
cele 32 de registre din fisierul de registre poate fi desemnat a fi unul din
registrele de uz general din arhitectura x86 (EAX, EBX, ECX, EDX, ESI, EDI,
EBP si ESP). Pentru fiecare operatie de scriere intr-un registru este
selectat un nou registru fizic, pentru a se retine temporar si data precedenta.
Redenumirea registrelor elimina efectiv toate dependintele WAW si WAR. Pentru
programator este transparent acest mod de redenumire a registrelor; este transparent
atat pentru sistemul de operare, cat si pentru programele aplicatie.
Exemplul 1. Redenumirea registrelor elimina dependentele de tipul scriere dupa
citire (WAR). O dependenta de tip WAR apare atunci cand prima dintr-o
pereche de instructiuni citeste un registru logic si a doua instructiune scrie
in acelasi registru. Acest tip de dependenta este ilustrat de perechea
de instructiuni de mai jos:
banda X banda Y
(1) MOV BX, AX (2) ADD AX, CX
(BX <- AX) (AX <- AX + CX)
(Ordinea initiala din program a instructiunilor este aratata de numerele din
paranteze.)
In absenta redenumirii registrelor, instructiunea ADD din banda de asamblare
Y ar trebui sa astepte pana cand instructiunea MOV din banda de
asamblare X ar citi registrul AX.
Insa, procesorul 6x86 evita blocarea benzii de asamblare intr-o
astfel de situatie. Pe masura ce este executata fiecare instructiune, rezultatele
sunt plasate intr-un nou registru fizic, pentru a evita posibilitatea
suprascrierii unei valori a unui registru logic si pentru a permite executia
in paralel a doua instructiuni fara blocare (fara a fi necesara nici o
secventiere la accesarea aceleiasi resurse) (Tab.1).
Exemplul 2. Redenumirea registrelor elimina dependentele de tipul scriere dupa
scriere (WAW)
O dependenta WAW apare cand doua instructiuni consecutive realizeaza scrierea
in acelasi registru logic. Acest tip de dependenta este ilustrat de:
banda X banda Y
(1) ADD AX, BX (2) MOV AX, amemi
(AX <- AX + BX) (AX <- amemi)
Fara denumirea registrelor instructiunea MOV din banda de asamblare Y ar trebui
sa fie intrerupta pentru a garanta ca instructiunea ADD din banda X si-a
depus rezultatul in AX (Tab.2).
Inaintarea datelor (Data Forwarding)
Doar redenumirea registrelor, nu poate elimina dependentele de tipul citire
dupa scriere (RAW). 6x86 foloseste doua tipuri de data forwarding impreuna
cu redenumirea registrelor pentru a elimina acest tip de dependente: -inaintarea
operandului (operand forwarding), - apare cand prima dintr-o pereche de
instructiuni efectueaza o citire din registru sau memorie iar aceasta data este
necesara celei de-a doua instructiuni. CPU executa operatia de citire si furnizeaza
data citita ambelor instructiuni; -inaintarea rezultatului (result forwarding)
- apare atunci cand prima dintr-o pereche de instructiuni executa o operatie
(cum ar fi ADD) iar rezultatul ei este citit de o a doua instructiune. CPU-ul
executa operatia primei instructiuni si depune rezultatul operatiei in
destinatiile ambelor instructiuni simultan.
Exemplul 3. Inaintarea operandului elimina dependenta de tipul RAW
O dependenta de tipul RAW apare cand prima dintr-o pereche de instructiuni
realizeaza o scriere iar a doua instructiune citeste acelasi registru.
banda X banda Y
(1) MOV AX, amemi (2) ADD BX, AX
(AX <- amemi) (BX <- AX + BX)
Inaintarea operandului poate apare doar daca prima instructiune nu modifica
valoarea initiala a datei (Tab. 3).
Exemplul 4. Inaintarea rezultatului elimina dependenta de tipul RAW
O dependenta de tipul RAW apare cand prima dintr-o pereche de instructiuni
realizeaza o scriere iar a doua instructiune citeste acelasi registru.
banda X banda Y
(1) ADD AX, BX (2) MOV amemi, AX
(AX <- AX + BX) (amemi <- AX)
A doua instructiune trebuie sa fie o instructiune de transfer iar destinatia
ei poate fi sau un registru sau o locatie de memorie (Tab. 4).
Evitarea datelor (Data Bypassing)
Pe langa redenumirea registrelor si inaintarea datelor, 6x86 contine
o a treia tehnica de eliminare a dependentelor de date, denumita evitarea datelor.
Aceasta reduce scaderilor in performanta ale acelor dependente de tipul
RAW din memorie ce nu pot fi eliminate cu ajutorul inaintarii datelor.
Evitarea datelor apare cand prima dintr-o pereche de instructiuni scrie
in memorie si urmatoarea citeste aceeasi data din memorie. 6x86 retine
data din prima instructiune si o paseaza celeilalte instructiuni, astfel eliminandu-se
un ciclu de citire din memorie.
Exemplul 5. Evitarea datei in dependenta de tipul RAW
In acest exemplu, dependenta de tipul RAW apare cand prima instructiune
efectueaza o scriere in memorie iar instructiunea urmatoare citeste aceeasi
locatie de memorie (Tab. 5).
banda X banda Y
(1) ADD amemi, AX (2) SUB BX, amemi
(amemi <- amemi + AX) (BX <- BX - amemi)
Controlul ramificatiilor
In programe instructiunile de salt apar in proportie de 20-25%.
Cand fluxul de secventiere normala al programului se schimba datorita
unei instructiuni de salt, nivelele benzilor de asamblare trebuie blocate pana
cand CPU-ul calculeaza adresa, aduce si decodifica noul flux de instructiuni.
Procesorul Cyrix 6x86 minimizeaza degradarea in performanta si latenta
introduse de instructiunile de salt prin folosirea conceptelor de prezicere
a salturilor si executie speculativa.
Prezicerea salturilor
Procesorul 6x86 foloseste un tabel al adreselor destinatie (Branch Target Buffer
- BTB) cu 256 de intrari, set asociativ pe 4 cai, pentru mentinerea adreselor
destinatie ale instructiunile de salt si a altor informatii necesare prezicerii
acestor salturi. In timpul aducerii codului instructiunii sunt cautate
instructiunile de salt in fluxul de instructiuni. Daca este descoperita
o instructiune de salt neconditionat, CPU-ul acceseaza BTB pentru a afla adresa
destinatie a instructiunii de salt. Daca aceasta adresa exista in BTB,
CPU-ul incepe sa aduca instructiunile de la noua adresa.
In cazul salturilor conditionate, BTB mai mentine o serie de informatii
cu privire la istoricul efectuarii saltului respectiv (pentru a se putea lua
decizia de efectuare sau nu a saltului). Daca instructiunea de salt conditionat
este gasita in BTB, 6x86 incepe aducerea instructiunilor de la adresa
prezisa. Daca instructiunea nu este gasita in BTB, 6x86 prezice neexecutarea
saltului si aducerea instructiunilor va continua cu adresa urmatoare. Decizia
de efectuare sau nu a saltului este luata pe baza unui algoritm de prezicere
a salturilor.
Odata ce a fost adus codul unei instructiuni de salt conditionat, aceasta este
decodificata si distribuita spre executie benzii de asamblare X. Instructiunea
trece prin nivelele benzii de asamblare X si este terminata sau in nivelul
EX sau in WB, in functie de instructiunea care a setat indicatorii
de conditii: -daca instructiunea care a setat indicatorii de conditii este executata
in paralel cu instructiunea de salt conditionat, atunci aceasta este terminata
in nivelul WB, -daca instructiunea care a setat indicatorii de conditii
a fost executata inaintea instructiunii de salt, atunci aceasta se va
termina in EX.
Instructiunile de salt conditionat corect prezise se vor executa intr-un
singur impuls de tact. Daca dupa terminarea executiei instructiunii de salt
conditionat s-a detectat o prezicere eronata a saltului, CPU-ul goleste benzile
de asamblare si incepe executia de la adresa corecta. Procesorul 6x86
in cazul unei instructiuni de salt conditionat aduce in avans atat
instructiunea prezisa cat si cealalta, dar o trimite benzii de asamblare
spre executie doar pe cea prezisa. Astfel ca, in cazul unei preziceri
eronate, instructiunea de la adresa neprezisa nu va mai fi citita din cache,
deoarece a fost adusa deja. Daca instructiunea de salt conditionat a fost rezolvata
in nivelul EX, atunci intarzierea in cazul unei preziceri
eronate este de patru impulsuri de tact, iar daca instructiunea de salt a fost
rezolvata doar in WB, atunci intarzierea este de cinci impulsuri
de tact.
Deoarece instructiunea de revenire dintr-o subrutina (RET) este dinamica, procesorul
6x86 mentine adresele pentru aceste instructiuni intr-o stiva cu opt intrari.
Adresa de revenire este introdusa in stiva adreselor de revenire de catre
instructiunea CALL, si este scoasa de catre instructiunea RET corespunzatoare.
Executia speculativa
Procesorul 6x86 are posibilitatea de a executa speculativ instructiunile urmatoare
unei instructiuni in virgula flotanta sau a unei instructiuni de salt.
Executia speculativa permite benzilor de asamblare sa execute continu instructiuni
dupa un salt, fara a fi necesara blocarea benzii de asamblare pana la
obtinerea rezultatului executiei instructiunii de salt conditionat. Acelasi
mecanism este folosit pentru a se executa instructiuni in virgula flotanta
in paralel cu instructiunile de numere intregi.
Procesorul are posibilitatea de executie in patru nivele de speculatie.
Dupa generarea unei noi adrese prin mecanismul de predictie, CPU-ul salveaza
starea curenta (registrele, indicatorii de conditii, etc.), incrementeaza numaratorul
nivelului de speculatie si incepe executia fluxului de instructiuni prezis.
Odata ce instructiunea de salt a fost rezolvata, CPU-ul decrementeaza nivelul
de speculatie. Pentru un salt corect prezis este stearsa starea resurselor salvate
la intrarea in nivelul de speculatie curent. Pentru un salt prezis eronat,
procesorul 6x86 genereaza adresa corecta pentru urmatoarea instructiune si foloseste
valorile de stare salvate pentru a restaura starea curenta, intr-un singur
impuls de tact.
Pentru a se mentine compatibilitatea, nu sunt permise scrierile in memorie
sau cache, pana cand nu este rezolvata instructiunea de salt. Executia
speculativa continua pana cand apare una din urmatoarele conditii:
-este decodificata o noua instructiune de salt sau de calcul in virgula
flotanta si nivelul de speculatie este patru (maximul) , -apare o exceptie sau
o eroare, -tamponul de scriere este plin, -se incearca modificarea unei
resurse a carei stare nu a fost salvata (registrele segment, indicatorii sistem).
Cache-ul unificat de date si instructiuni
Procesorul Cyrix 6x86 contine un cache unificat si un cache de instructiuni
(Fig. 5). Cache-ul unificat cu dimensiunea de 16Ko functioneaza ca un cache
primar (L1) de date si ca un cache secundar (L2) de instructiuni. Configurat
ca un cache set-asociativ pe patru cai, contine pana la 16Ko de cod si
date in 512 linii. Cache-ul este dual-port si permite executarea a doua
din operatiile urmatoare in paralel: -citirea unui cod de instructiune,
-citirea unei date (de catre banda X, banda Y sau FPU) , -scrierea unei date
(de catre banda X, banda Y sau FPU).
Acest cache foloseste un algoritm de replasare pseudo-LRU (Last Recently Used)
si poate fi configurat sa aloce o noua linie de cache doar la un miss de citire,
sau si la citire si la scriere.
Cache-ul de instructiuni de 256 octeti complet asociativ serveste drept cache
de instructiuni primar (L1). Cache-ul de instructiuni este incarcat din
cache-ul unificat prin magistrala de date interna. Citirile codurilor de instructiuni
din unitatea pentru numere intregi care se gasesc in cache-ul de
instructiuni nu mai acceseaza cache-ul unificat. Daca instructiunea nu este
gasita in cache-ul de instructiuni, linia din cache-ul unificat care contine
instructiunea respectiva, este transferata atat cache-ului de instructiuni
cat si unitatii pentru numere intregi.
Acest cache foloseste tot algorimtul de replasare pseudo-LRU. Pentru a se asigura
operarea corecta in cazul codului automodificabil, orice scriere in
cache-ul unificat este verificata cu continutul cache-ului de instructiuni.
Daca a fost modificata o locatie care este prezenta si in cache-ul de
instructiuni, atunci linia ce contine respectiva locatie este dezactivata.
Unitatea de gestionare a memoriei
Unitatea de gestionare a memoriei (Memory Management Unit - MMU) a procesorului
Cyrix 6x86, prezentata in Fig. 6, translateaza adresele liniare furnizate
de IU intr-o adresa fizica, pentru a putea fi utilizata in continuare
de cache si interfata cu magistrala. MMU include doua mecanisme de paginare,
un mecanism traditional si un mecanism specific lui 6x86 cu pagini de dimensiuni
variabile (Fig. 6).
Mecanismul de paginare cu dimensiunea paginilor variabila
Acest mecanism de paginare permite programelor sa mapeze pagini cu dimensiunea
intre 4Ko si 4Go. Folosirea paginilor de dimensiuni mari poate duce la
sporirea performantei unor anumite aplicatii.
Mecanismul traditional de paginare
Mecanismul traditional de paginare a fost imbunatatit la 6x86 prin adaugarea
unui cache pentru tabelul directorilor (Directory Table Entry -DTE) si un TLB
victima. TLB-ul principal este cu mapare directa si contine 128 de intrari pentru
tabelul paginilor. Cache-ul DTE cu patru intrari complet asociative contine
accesele cele mai recente la DTE.
TLB-ul victima contine liniile din TLB principal care au fost inlocuite
datorita unui miss in TLB. Daca se face referirea la o pagina ce are PTE-ul
in TLB-ul victima, linia aceasta este schimbata cu o linie din TLB-ul
primar.
Unitatea in virgula flotanta
Interfata dintre unitatea in virgula flotanta (FPU) a procesorului 6x86
si unitatea pentru numere intregi este realizata printr-o magistrala interna
pe 64 de biti. Setul de instructiuni FPU al procesorului 6x86 este compatibil
x87 si adera standardului IEEE-754.
Procesorul Cyrix 6x86 executa instructiunile intregi in paralel
cu instructiunile in virgula flotanta. Instructiunile intregi pot
fi executate in inordine cu respectarea instructiunilor FPU.
Asa cum s-a mai spus, instructiunile FPU sunt intotdeauna executate in
banda de asamblare X. Nivelul pentru calculul adresei din banda X verifica aparitia
exceptiilor de gestionare a memoriei si acceseaza operanzii din memorie folositi
de FPU. Daca nu apare nici o exceptie, se salveaza starea curenta a procesorului
in AC2 si trimite instructiunea in virgula flotanta spre executie
FPU-ului. Apoi unitatea centrala poate executa orice instructiune intreaga
urmatoare, speculativ si in inordine.
Unitatea centrala 6x86 poate trimite pana la patru instructiuni FPU in
coada de asteptare a FPU. CPU-ul continua cu executia speculativa si in
inordine pana cand apare una dintre conditiile ce cauzeaza oprirea
executiei speculative. Pe masura ce FPU termina de executat o instructiune in
virgula flotanta, este decrementat nivelul speculativ si sunt sterse valorile
de stare salvate la inceputul acestei instructiuni. Unitatea in
virgula flotanta mai contine si un set de patru tampoane de scriere pentru a
preveni intreruperile datorate scrierilor speculative.
Procesoarele Cyrix 6x86MX si MII
Aceste procesoare au la baza nucleul procesorului 6x86, imbunatatit cu
cele 57 instructiuni multimedia noi, compatibile cu tehnologia MMX. In
plus, 6x86MX si MII lucreaza la frecvente mai mari, contin un cache de dimensiune
mai mare, un tampon destinat translatarii adreselor liniare in adrese
fizice (TLB) pe doua nivele si un cache destinat adreselor de salt imbunatatit
(Fig. 7).
Pentru a oferi suportul pentru operatiile multimedia, cache-ul poate fi transformat
intr-o memorie RAM scratchpad. Aceasta memorie functioneaza ca o memorie
privata pentru CPUsi nu participa in operatiile cache.
Evolutia procesoarelor
Pana unde se poate merge in directia miniaturizarii si cresterii
performantelor?
O privire asupra dezvoltarii procesoarelor de la origini pana in
prezent ne poate permite sa caracterizam arhitecturile microprocesoarelor contemporane
si chiar sa incercam sa prevedem cum vor arata cele de maine.
Am intalnit de mai multe ori un banc pe Internet, care spunea ca,
daca masinile ar fi evoluat in aceeasi masura cu calculatoarele, acum
ar fi mers 120 de kilometri cu benzina dintr-o bricheta si ar fi costat cat
o paine. Pe de alta parte, un contra-banc, din partea industriei automobilistice,
ofensate, zicea apoi ca, daca ar fi evoluat la fel, masina ar fi refuzat sa
mai mearga de cateva ori pe zi, si ar fi trebuit sa o duci inapoi
in garaj ca sa reporneasca.
Adevarul este ca progresele facute de tehnologia calculatoarelor sunt absolut
uluitoare; ajunge sa iti cumperi un calculator nou dupa doi ani ca sa
fii impresionat de castigul de performanta inregistrat. Sporul de
performanta se datoreaza unor procesoare din ce in ce mai sofisticate
si mai rapide, si unor memorii de capacitati din ce in ce mai mari.
Raspunzatoare pentru cresterea exponentiala a performantei sunt insa in
cea mai mare masura microprocesoarele. In acest articol vom arunca o privire
asupra evolutiei microprocesoarelor de la origini pana in prezent.
Vom incerca apoi sa caracterizam arhitecturile procesoarelor contemporane
si sa extrapolam din datele la dispozitie, speculand despre unele din
posibilele evolutii viitoare.
Trebuie sa atrag de la inceput atentia ca nu am insusiri paranormale
si, ca atare, nu sunt profet. Domeniul tehnologiilor de calcul este extraordinar
de volatil si se misca cu o viteza fantastica; orice previziune este cel putin
hazardata. De altfel caseta "Performante - estimari" ilustreaza acest
fapt, contrapunand previziunile din urma cu cativa ani ale unei
organizatii extrem de prestigioase, Semiconductor Industry Association (SIA,
https://www.semichips.org/), cu realitatea. Deci nu va asteptati de la mine la
mai mult.
Am mai publicat in PC Report o serie intreaga de articole despre
arhitectura procesoarelor moderne, pe care le voie cita ocazional; toate acestea
sunt disponibile din pagina mea de web. Articolul de fata va fi insa mai
superficial. Exista o cantitate enorma de informatie pe web. In acest
articol am folosit in mod repetat informatii de la https://bwrc.eecs.berkeley.
edu/CIC/, CPU Info Center.
Aspecte economice
Un istoric interesant al diferitelor idei arhitecturale din microprocesoare
puteti gasi pe web la https://bwrc.eecs.berkeley.edu/CIC/archive/ cpu_history.html.
Primul microprocesor a fost creat de firma Intel in 1971. Numele sau era
Intel 4004, si era un procesor pe 4 biti. Aparitia primului microprocesor a
fost un pas cu uriase consecinte in evolutia ulterioara a sistemelor de
calcul. Diferenta intre microprocesor si metodele indeobste folosite
era ca procesorul strange pe o singura pilula de siliciu toate unitatile
functionale importante necesare executarii programelor; fiind toate strans
integrate, comunicatia intre ele este rapida si eficace, permitand
dintr-o data un salt calitativ.
Nu mai putin importanta este reducerea de cost care urmeaza unei astfel de integrari.
Cu siguranta ca principalul motiv al evolutiei explozive a tehnologiei circuitelor
integrate nu este de natura tehnologica, ci economica: spirala preturilor din
ce in ce mai scazute face echipamentele de calcul din ce in ce mai
accesibile, cererea creste, ducand la venituri mai ridicate pentru fabricanti,
care investesc mai mult in cercetare/dezvoltare si linii tehnologice,
obtinand densitati mai mari, permitand integrarea mai multor circuite
precum si costuri si mai scazute. Cu toata scaderea de pret, veniturile globale
ale industriei semiconductoarelor au crescut in mod galopant: numai anul
trecut vanzarile globale au fost de 149 de miliarde de dolari!
Esential pentru a mentine aceasta spirala este faptul ca echipamentele de calcul
maresc enorm productivitatea muncii, direct sau indirect: de aici cererea crescanda.
Iar expertii afirma ca acesta este doar inceputul si ca in viitor
fiecare individ va depinde de zeci de dispozitive de calcul in fiecare
clipa. Nu suntem prea departe de acest punct: chiar in ziua de azi, o
masina moderna are in medie 15 microprocesoare, care controleaza, regleaza
si diagnosticheaza tot felul de parametri, de la injectie pana la frane.
Nu pot sa ma abtin sa remarc ca Statele Unite ale Americii atribuie o treime
din cresterea venitului national brut in anul trecut doar tehnologiilor
informationale, care insa ocupa doar 8% din forta de munca. In foarte
mare masura, tehnologia informatiei este responsabila pentru fenomenala dezvoltare
economica pe care Statele Unite o traverseaza in acesti ani.
Aspecte cantitative
Sa lasam acum deoparte economia, si sa aruncam o privire asupra evolutiei unor
parametri ai procesoarelor de-a lungul timpului. Tabela "Cronologia Intel"
prezinta evolutia generatiilor succesive ale celei mai proeminente familii de
procesoare, ale firmei Intel.
Ultima coloana din tabel si figura "Performante - estimari" arata
care este impactul miniaturizarii: aceasta coloana indica dimensiunea de baza
(feature size), care poate fi vazuta ca fiind dimensiunea unui tranzistor. Orice
reducere a acestei valori are un impact cvadratic, pentru ca suprafata creste
cu patratul laturii. O reducere de la 2 microni la 1,5 (50%) mareste deci suprafata
efectiva cu 77% (4/2,25 = 1,77).
Din fericire, reducerea dimensiunilor mai are inca o consecinta foarte
importanta: traseele pe care trebuie sa le parcurga curentul electric intre
dispozitive devin mai scurte, deci se pot parcurge mai rapid. Proiectantii pot
face deci procesorul sa functioneze cu un ceas mai rapid.
Observatie: Majoritatea covarsitoare a procesoarelor contemporane functioneaza
in mod sincron: intreaga lor functionare este orchestrata de un
tact de ceas, care garanteaza ca feluritele parti sunt sincronizate. Din ce
in ce mai mult insa se tinde spre scheme cu multiple semnale de
ceas, sau chiar scheme asincrone. Nu ne vom ocupa insa de aceste evolutii
in textul acestui articol.
Faptul ca avem siliciu la dispozitie pentru a implementa mai multi tranzistori
inseamna ca:
1). Putem muta mai multe circuite auxiliare pe acelasi cip. Evolutia procesoarelor
cunoaste cateva salturi calitative: cand miniaturizarea facea posibila
integrarea unui nou dispozitiv pe acelasi circuit integrat, se realiza un salt
de performanta. Astfel, au fost integrate succesiv: unitati din ce in
ce mai mari de procesare (8, 16, 32, acum 64 de biti), coprocesoare aritmetice,
unitati de management al memoriei, cache-uri de nivel 1 si chiar 2;
2). Designerii folosesc tranzistorii suplimentari pentru a construi circuite
mai sofisticate, care pot executa mai repede si mai eficient programele. Metoda
fundamentala folosita este de a face mai multe lucruri in paralel.
Impreuna aceste trei fenomene (viteza ceasului, integrarea pe o singura
pastila si exploatarea paralelismului) contribuie la cresterea performantei
totale a procesoarelor. Asa cum am povestit si cu alte ocazii, masurarea performantei
unui calculator se face evaluand sistemul pe mai multe programe (deci
performanta depinde foarte mult si de compilatorul folosit), care de obicei
fac parte din suite de teste standardizate (benchmark suites). Cele mai folosite
pentru a evalua procesoare sunt cele din seria SPEC (Standard Performance Evaluation
Corporation, https:// www.specbench.org). Nu ne va interesa acum prea tare ce
reprezinta numerele acestea; cert este ca cu cat sunt mai mari, cu atat
e mai bine. Graficul din figura "Performante - SPEC" arata evolutia
performantei procesoarelor in ultimii 10 ani, in termeni SPEC.
Evolutia urmareste aproximativ o curba exponentiala: in fiecare an performanta
creste cu 60%.
Tehnologii arhitecturale
Asa cum am ilustrat in seria mea de articole intitulate "Arhitectura
avansata a procesoarelor", o multime de inovatii tehnologice au fost introduse
una dupa alta in arhitecturi; de fapt intentionez sa continui aceasta
serie si in viitor, pentru ca mai sunt de prezentat si alte mecanisme
importante.
Imi permit sa prezint in continuare viziunea profesorului John Hennessy,
de la universitatea Stanford, asa cum a expus-o in prelegerea pe care
a tinut-o ca invitat la Federated Computer Research Conferences, in mai
1999.
Hennessy vede doua tehnologii arhitecturale ca fiind esentiale: exploatarea
paralelismului la nivel de instructiune (Instruction Level Parallelism, ILP)
si ierarhii sofisticate de memorie (cache-uri). Sa spunem cateva cuvinte
despre fiecare:
ILP
Paralelismul la nivel de instructiune consta in independenta instructiunilor
din programe una de alta, ceea ce ne permite sa executam mai multe instructiuni
simultan. Am vorbit altadata pe larg despre paralelismul la nivel de instructiune;
sa observam ca toate procesoarele contemporane il exploateaza prin doua
forme:
Executia pe banda de asamblare (pipeline) a instructiunilor succesive;
Executia in paralel a instructiunilor independente: procesoarele de tip
VLIW (very long instruction word) aleg la compilare care instructiuni merg in
paralel, iar procesoarele superscalare fac aceasta alegere in timpul executiei.
Astfel, in 1985 au aparut primele procesoare cu banda de asamblare, in
1990 primele procesoare de tip VLIW, iar in 1995 procesoare foarte sofisticate
superscalare, care pot executa instructiunile in ordini foarte diferite
de cea din program (out-of-order execution).
Cache-uri
Am scris in repetate randuri despre cache-uri in PC Report
(de pilda martie 1997 si noiembrie 1998). Aici vom arunca doar o privire superficiala
asupra lor; scopul nostru este de a intelege de ce cache-urile joaca un
rol fundamental in cresterea performantei. Figura "Performante -
memorii si procesoare" ne ofera cheia: desi atat procesoarele cat
si memoriile cresc constant in viteza, cresterea procesoarelor este cu
50% mai rapida decat a memoriilor. Ca atare exista o disparitate crescanda
intre nevoile de date (si instructiuni) ale procesorului si ceea ce memoriile
pot oferi. Durata unui acces la memorie ajunge la zeci de cicli de ceas pentru
procesoarele contemporane. Intarzierea accesului este si mai exacerbata
in cazul sistemelor care au mai multe procesoare, in care caz timpii
de acces la date pot ajunge la mii de cicli.
Din aceasta cauza se construiesc cache-uri, care sunt memorii mai mici si mai
rapide, care se plaseaza intre procesor si memoria principala, si in
care sunt aduse datele pentru prelucrare. Proiectantii au reusit sa sporeasca
eficacitatea cache-urilor folosind doua metode:
(a) Prin folosirea unor cache-uri din ce in ce mai mari, plasate din ce
in ce mai aproape de procesor. Aceasta evolutie este clar vizibila:
Primele procesoare nu aveau nici un fel de cache, pentru ca memoriile erau suficient
de rapide pentru a le servi cu date. In 1980 au aparut cache-uri (L1)
sub forma unor circuite speciale, care in 1984 au fost integrate pe aceeasi
pilula de siliciu cu procesorul central, dupa care (1986) a aparut un al doilea
nivel de cache (L2), mai mare si ceva mai lent, care in procesoarele moderne
(1995) este la randul lui adesea integrat cu circuitul microprocesorului,
pentru a permite un acces rapid. Au aparut nivele tertiare de cache (1999).
(b) Pe de alta parte metodele de management ale cache-urilor sunt din ce in
ce mai sofisticate:
Au aparut cache-uri care servesc procesorul de indata ce primul cuvant
a sosit, chiar daca restul sunt pe drum (early restart, 1992), cache-uri care
nu blocheaza procesorul cand datele lipsesc, ci ii permit sa continue
executia (non-blocking, 1994) si tot felul de alte tehnologii sofisticate, pe
care le-am expus in alte parti (cache-uri victima, buffere de scriere,
instructiuni speciale (prefetching) de management al cache-ului etc.). Tot aici
se cuvine sa mentionam multiprocesoarele simetrice si protocoalele de coerenta
ale cache-urilor pentru astfel de sisteme; toate procesoarele moderne sunt construite
pentru a fi folosite in sisteme multi-procesor, si includ astfel de dispozitive.
Arhitecturile contemporane
Astfel, urmarind evolutia arhitecturilor, am ajuns pana in ziua
de azi. Vom incerca sa caracterizam sumar starea arhitecturilor, dupa
care vom arunca o privire asupra unora din directiile viitoare.
Hardware si software. Istoria moderna a procesoarelor contrapune doua paradigme
pentru cresterea performantei, bazate pe software si respectiv pe hardware.
Aparent, un articol despre arhitectura procesoarelor nu are nimic de-a face
cu softul. Nimic mai gresit: la ora aceasta exista o simbioza totala intre
hardware si software. Procesoarele se proiecteaza odata cu compilatoarele care
le folosesc iar relatia dintre ele este foarte stransa: compilatorul trebuie
sa genereze cod care sa exploateze caracteristicile arhitecturale, altfel codul
generat va fi foarte ineficace.
Metodele de crestere a performantei cu ajutorul compilatoarelor se numesc si
statice, pentru ca programul este analizat si optimizat o singura data, inainte
de a fi pornit in executie. Metodele bazate pe hardware se numesc dinamice,
pentru ca sunt aplicate in timp ce programul se executa.
Istoria arhitecturilor contrapune mereu cele doua paradigme: de exemplu dezbaterea
initiala RISC/CISC era de aceeasi natura, ca si dezbaterea intre superscalar
si VLIW, pe care am mentionat-o deja in acest text.
Nota: In anii '80 a aparut ideea de a face procesoarele mult mai simple
pentru a le permite sa mearga mai repede. Astfel de arhitecturi au fost numite
RISC: Reduced Instruction Set Computer, prin contrast cu celelalte, Complex
ISC.
De fapt, asa cum mentionam si in alte articole (de exemplu in PC
Report din iunie 1999), exista lucruri care se pot face numai static si exista
lucruri care se pot face numai dinamic. Asa ca de fapt, chiar arhitecturile
care pornesc la una din extreme, tind sa convearga catre folosirea unui amestec
de trasaturi din ambele domenii:
La ora actuala distinctia RISC/CISC aproape ca s-a estompat. De exemplu, Pentium,
un procesor tipic CISC, de fapt traduce in mod automat instructiunile
in instructiuni de tip RISC in hardware, dupa care le executa. Pe
de alta parte, toate procesoarele RISC au capatat extensii la setul de instructiuni
(gen CISC) pentru a le mari eficacitatea; de pilda toate procesoarele au extensii
speciale pentru multimedia.
De asemenea, granitele dintre super-scalar si VLIW tind sa se estompeze, fiecare
imprumutind din tehnologiile celuilalt.
Cu siguranta ca un model mixt este preferabil, pentru ca poate lua ce e mai
bun din fiecare tehnologie.
Crusoe
Se cuvine sa atragem atentia asupra unei recrudescente a "luptei"
sistemelor pure: anul acesta compania Transmeta a anuntat aparitia unui nou
procesor, numit Crusoe, care exploateaza la maximum tehnologiile statice (compilarea).
Compania Transmeta a facut mare valva, nu atat prin procesorul lor,
care poate simula alte procesoare, inclusiv cele ale firmei Intel, ci prin faptul
ca angajeaza pe cel mai faimos programator al planetei, Linus Torvalds, creatorul
sistemului de operare Linux.
Transmeta a lansat Crusoe cu mare pompa in luna ianuarie; compania predica
intoarcerea la simplitate (care a fost sugerata atat de curentul
RISC, cat si de modelele VLIW), in care hardul este simplu si rapid
iar compilatorul duce greul. Echipa care a lucrat la Transmeta este compusa
in mare masura din ingineri plecati de la IBM: IBM a lucrat la o versiune
de procesor PowerPC care putea face exact acelasi lucru: putea executa in
mod nativ cod x86 (adica compatibil Intel), dar proiectul lor a fost intrerupt
desi era intr-o stare foarte avansata, aparent din motive de marketing.
Cat de serios este acest nou competitor?
Din pacate atuurile lui Crusoe nu sunt prea clare:
· cipul nu are un ceas mai rapid decat procesoarele Intel (versiunile
de Crusoe disponibile acum merg doar la 400Mhz, comparativ cu Pentium, care
ajunge la 800);
· cipul intr-adevar consuma mult mai putina energie si are nevoie
de mult mai putina racire. Transmeta afirma ca asta-l face ideal pentru laptop-uri.
Din pacate, principalul consumator de energie intr-un laptop nu este procesorul,
ci ecranul si discul, asa incat avantajele noului cip vor fi marginale;
· Crusoe se bucura de compatibilitate cu setul de instructiuni x86; dar
pentru platformele pe care x86 este dominant (desktop, laptop, chiar si server)
am vazut ca performanta lui este insuficienta. Daca Crusoe vrea sa concureze
pentru celelalte piete, de procesoare integrate (embedded computing), atunci
are de-a face cu alti competitori formidabili, ca procesoarele de semnal de
la Motorola, Texas Instruments si Intel (ARM), asupra carora nu este clar cate
avantaje are.
Probabil ca pentru a ramane viabil, Crusoe va trebui sa se metamorfozeze
si sa devina mai complicat, folosind si o serie de mecanisme dinamice de crestere
a performantei.
In definitiv exista o singura resursa aproape gratuita si care este in
cantitati suficiente: numarul de tranzistori. Datorita miniaturizarii numarul
de tranzistori disponibili pentru design creste enorm; de aceea simplitatea
cu orice pret (asa cum o incarneaza Crusoe) nu este neaparat o calitate.
Constrangerile fizice
Proiectantii de microprocesoare se lovesc in ziua de azi de mai multe
dificultati. Nici una dintre ele nu e insurmontabila, dar solutiile sunt din
ce in ce mai grele. Vom arunca o privire asupra unora dintre ele; incercarea
de a extrapola impactul acestor bariere in viitor va sugera apoi solutii
pentru depasirea lor.
Accesul la memorie
Dupa cum am vazut in figura "Performante - memorii si procesoare",
in ultimii 10 ani viteza memoriilor a crescut cu 10% pe an, in timp
ce viteza procesoarelor a crescut cu o rata de 60%. Toate motivele ne indeamna
sa credem ca aceasta disparitate va continua sa se accentueze, si ca pretul
relativ al unui acces la memorie (masurat in cicli de ceas) va continua
sa creasca.
Putere
Un alt factor care limiteaza evolutia circuitelor integrate este consumul de
putere; in urma cu 15 ani un procesor consuma 2 wati; astazi un procesor
ca Alpha 80364 consuma 100W; de aici rezulta limitari pentru ceas (puterea consumata
creste cu frecventa ceasului), si necesitatea unor dispozitive speciale de racire.
Din fericire tehnologia lucreaza in directia favorabila: miniaturizarea
duce la scaderea puterii necesare. Un alt factor care duce la scaderea puterii
consumate este scaderea tensiunilor de alimentare.
Interesant este faptul ca, desi dimensiunea tranzistorilor a scazut intr-una,
dimensiunile circuitelor fabricate au crescut: foamea neostoita a designerilor
cere suprafete din ce in ce mai mari ale placutelor de siliciu; de aceea
puterea consumata a crescut si ea.
Complexitate
Un factor deloc neglijabil este complexitatea enorma a circuitelor. Procesoarele
cele mai moderne au peste 25 de milioane de tranzistoare, iar in cativa
ani designerii vor avea la dispozitie un miliard. Astfel de circuite sunt foarte
greu de verificat si testat. La ora actuala o companie ca Intel cheltuieste
40% din budget pentru proiectare si dezvoltare, si 60% pentru verificare si
testare!
O alta problema importanta este legata de liniile tehnologice de fabricatie:
o astfel de instalatie costa la ora actuala doua miliarde de dolari. Putine
companii isi pot permite investitii de asemenea anvergura pentru o tehnologie
care se schimba in 3 ani!
Sarmele
E clar ca miniaturizarea nu va putea continua in acelasi ritm exponential:
peste ceva vreme am ajunge la necesitatea de a face un tranzistor mai mic decat
un atom, ceea ce e evident imposibil. Dar chiar inainte de a atinge un
astfel de prag, vom avea alte probleme de infruntat.
O analiza extrem de interesanta a fost facuta de Mark Horowitz, profesor la
universitatea Stanford, intr-un articol intitulat "Viitorul sarmelor".
Articolul porneste de la caracteristicile electrice ale semiconductorilor si
analizeaza o serie de scenarii posibile pentru tehnologiile de fabricatie. Textul
ia in considerare tot felul de factori, cum ar fi geometria sarmelor,
capacitati si rezistente, disiparea puterii etc. Vom ignora toate aceste detalii,
insa vom privi una din concluziile la care autorul ajunge.
Autorul observa ca in general sarmele vor evolua in sensul
dorit: vor deveni mai scurte, iar viteza de transmisiune a informatiei nu va
scadea, relativ la dimensiunea circuitului. Deci daca am lua un microprocesor
de astazi si l-am reduce la scara, sarmele nu ar constitui un impediment
in functionarea sa corecta.
Problema apare insa din faptul ca de fapt suprafata circuitelor nu scade,
din cauza ca designerii adauga noi module. O mare problema sunt sarmele
care traverseaza mai multe module. Lungimea acestora ramane practic constanta,
in milimetri. Ori, cum viteza ceasului creste mereu, asta inseamna
ca semnalele electrice nu mai au timp sa parcurga sarmele de la un capat
la altul. La 1Ghz, lumina strabate in vid 30 de centimetri. Dar viteza
luminii in solide este mai mica iar viteza de propagare scade semnificativ
odata cu numarul de "consumatori" ai sarmei (adica o sarma
conectata la 3 circuite e mult mai lenta decat una cuplata la doar doua).
De asemenea, liniile lungi de transmisiune vor avea nevoie de amplificatoare,
care incetinesc substantial semnalul.
Asta inseamna ca circuitele viitorului nu vor mai putea comunica prin
semnale globale: pur si simplu va fi imposibil pentru o sarma sa uneasca
diferitele parti ale circuitului. Aceasta este o consecinta de cea mai mare
importanta pentru arhitecturile viitoare!
Zgomotul
In fine, pe masura ce tranzistorii sunt mai mici, sarmele sunt mai
subtiri si consumul de putere este mai mare, circuitele sunt mai sensibile la
zgomot, fie el termic, din mediu (de exemplu radiatii cosmice) sau, in
curand, chiar efecte cuantice! Fenomenele de transport din semiconductori
pe care se bazeaza tranzistorul sunt fenomene statistice: or, cand dimensiunile
devin atat de mici incat numai cativa electroni produc
semnalele, statistica nu mai opereaza iar exceptiile incep sa apara.
Generatia urmatoare
In aceasta ultima sectiune vom incerca sa discernem ce ne ofera
viitorul. Marile companii lucreaza simultan la mai multe generatii ale unui
procesor, cu echipe independente, ca atare ceva din ceea ce viitorul ne rezerva
poate fi observat in produsele comerciale in curs de proiectare,
in masura in care companiile dezvaluie astfel de informatii.
Cercetarea in arhitectura procesoarelor este efervescenta, atat
in industrie cat si in universitati; este absolut imposibil
de urmarit intregul peisaj. Iata insa unele dintre directii:
Evolutie incrementala
Un efort substantial este in continuare depus in a perfectiona tehnicile
care in ultimii 15 ani au servit atat de bine arhitectura, pe care
le-am descris mai sus: exploatarea paralelismului la nivel de instructiune si
ierarhiile de memorie.
Iata unele dintre tendinte:
Trace cache: este un cache pentru instructiuni care, in loc de a pastra
instructiunile in ordinea adreselor lor, le mentine in ordinea in
care este probabil sa fie executate.
Executia speculativa si predictia valorilor: intr-un articol anterior
din PC Report (din iulie 1999) am vazut ca principala limitare in calea
executiei paralele a instructiunilor sunt dependentele intre instructiuni:
una are nevoie de rezultatul alteia pentru a se executa. Or, daca prima instructiune
dureaza mult, atunci a doua nu se poate executa nici ea. Solutia ades folosita
este de a ghici valoarea rezultata si de a executa si instructiunea dependenta.
Cand rezultatul primei instructiuni soseste, este comparat cu cel ghicit
(prezis); daca predictia a fost corecta, toate sunt bune, altfel instructiunea
dependenta este re-executata. Exista felurite forme de predictie a valorilor,
unele folosite deja de multa vreme (cum ar fi predictia salturilor, pe care
am descris-o in PC Report din august 1999), dar este plauzibil ca scheme
din ce in ce mai sofisticate sa-si faca aparitia.
Executia predicata, care este deja folosita de procesoare de prelucrare de semnal
ca Texas Instruments C6X, si care va fi una din trasaturile fundamentale ale
noii arhitecturi de la Intel, Merced. Executia predicata evita executia instructiunilor
de salt (care au un efect negativ asupra performantei, asa cum am aratat in
articolul mai sus-citat) si prefera sa execute instructiuni in mod inutil
dupa care sa arunce rezultatele la gunoi (de exemplu, cand avem o structura
de genul if-then-else, o arhitectura predicata poate executa ambele ramuri ale
conditiei, dar va permite numai uneia dintre ele sa-si faca efectele vizibile).
Multi-procesoare
Asa cum am vazut, proiectantii tind sa inghesuie din ce in ce mai
multe cir