Jump to content
zbeng

Evolutia microprocesoarelor

Recommended Posts

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)

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

Corporaþia Cyrix este unul dintre furnizorii de bazã ai soluþiilor bazate pe microprocesoare, care a introdus noi standarde pe piaþa calculatoarelor personale. În ultimii zece ani Cyrix a dezvoltat aproape o duzinã de procesoare originale folosite în milioane de calculatoare din întreaga lume.

În luna noiembrie a anului 1997, Cyrix a fost cumpãratã de National Semiconductor. Aceastã fuziune a adus douã componente importante pentru Cyrix: capacitatea de producþie la nivel mondial a National Semiconductor ºi infrastructura necesarã acestei producþii.

Primul produs Cyrix a fost un coprocesor matematic destinat creºterii vitezei de realizare a calculelor matematice. Succesul acestui coprocesor matematic a permis celor de la Cyrix sã distribuie începând cu 1992, primul procesor din familia x86. Compania a dezvoltat rapid o linie de producþie pentru procesoarele 486, ºi apoi pentru procesoarele din generaþia a cincea 5x86, un CPU pentru sistemele PC (mobile ºi desktop). În 1995, Cyrix a introdus procesorul din generaþia a ºasea, 6x86, un procesor superscalar, bazat pe o superbandã de asamblare; în iunie 1997, a introdus procesorul MMX 6x86MX, iar în 1998 a apãrut procesorul MII.

Procesorul Cyrix 5x86

Familia de procesoare 5x86 reprezintã o nouã generaþie pe 64 de biþi compatibilã x86. Unitatea centralã se bazeazã pe o bandã de asamblare cu ºase nivele, putând executa o instrucþiune într-un impuls de tact.

Unitatea centralã 5x86 este divizatã în urmãtoarele blocuri funcþionale (Fig. 1): -unitatea pentru numere întregi (Integer Unit - IU), -unitatea în virgulã flotantã (Floating Point Unit - FPU) , -unitatea cache (Write-Back Cache) , -unitatea pentru gestiunea memoriei (Memory Management Unit - MMU) , -unitatea de interfaþã cu magistrala (Bus Interface Unit - BIU).

Unitatea pentru numere întregi conþine: -tamponul pentru instrucþiuni (Instruction Buffer - IB) , -unitatea de aducere a instrucþiunii (Instruction Fetch Unit - IF) , -unitatea de decodificare a instrucþiunii (Instruction Decoder Unit - ID).

Instrucþiunile sunt executate în unitatea pentru numere întregi sau în unitatea de calcul în virgulã flotantã. Cache-ul conþine cele mai recent utilizate date ºi instrucþiuni ºi asigurã accesul rapid la aceste date din partea IU ºi FPU.

Când apare o cerere de acces la o locaþie din memoria externã, MMU calculeazã adresa fizicã pe care o trimite unitaþii de interfaþã cu magistrala, care asigurã interfaþarea unitaþii centrale cu memoria externã ºi celelalte circuite de pe placa de bazã.

Unitatea pentru numere întregi

Aceastã unitate citeºte, decodificã ºi executã intrucþiunile într-o bandã de asamblare cu ºase nivele (Fig. 2): -nivelul de aducere al codului instrucþiunii (Instrucþion Fetch - IF) - citeºte din cache codul instrucþiunii urmãtoare ºi îl trimite spre decodificare nivelului urmãtor din banda de asamblare. Se pot citi pânã la 128 de octeþi într-un impuls de tact, -nivelul de decodificare a instrucþiunii (Instruction Decode - ID) - evalueazã ºirul de octeþi primit de la nivelul IF, determinând numãrul de octeþi pentru fiecare instrucþiune ºi tipul acesteia, pe care apoi le decodificã la viteza de o instrucþiune într-un impuls de tact, -primul nivel de caclul al adresei (Address Calculation 1 - AC1) - dacã instrucþiunea are un operand în memorie, acest nivel calculeazã adresa de memorie liniarã pentru instrucþiune, -al doilea nivel de caclul al adresei (Address Calculation 2 - AC2) - realizeazã toate funcþiile de gestionare a memoriei, accesarea cache-ului ºi a registrelor. Dacã detecteazã o instrucþiune în virgulã flotantã, aceasta este trimisã pentru execuþie unitãþii în virgulã flotantã, -nivelul de execuþie (Execution - EX) - executã instrucþiunea folosind operanzii furnizaþi de nivelele pentru calculul adresei, -nivelul write-back (WB) - ultimul nivel din IU, actualizeazã setul de registre sau trimite rezultatul unitãþii de interfaþã cu memoria (Load/Store Unit) din MMU.

Unitatea cache

Procesorul Cyrix 5x86 conþine un cache unificat pentru date ºi instrucþiuni de 16Ko, set-asociativ pe patru cãi, organizat pe 1024 de linii. Scrierile în cache se fac prin metoda write-back. Memoria cache este organizatã în patru bancuri a câte 256 linii fiecare, cu 16 octeþi pe linie. Fiecare linie cache are asociat câte un tag pe 21 de biþi ºi un bit de valid (aratã dacã linia conþine informaþii valide sau nu). Pe lângã aceºti biþi, fiecare linie mai conþine încã patru biþi care indicã dacã conþinutul liniei a fost modificat (dirty bits), câte unul pentru fiecare dublu-cuvânt din linie. Aceºti ultimi patru biþi permit marcarea independentã a fiecãrui dublu-cuvânt ca fiind modificat, în loc de a marca întreaga linie ca fiind modificatã.

Unitatea de gestionare a memoriei

MMU translateazã adresele liniare furnizate de IU în adrese fizice, pentru a putea fi folosite de unitatea cache ºi unitatea de interfaþã cu magistrala. Mecanismul de paginare este cel standard x86.

Unitatea pentru gestionarea memoriei mai conþine un bloc (Load/Store Unit) care planificã accesele la memoria cache ºi memoria externã ºi implementeazã urmãtoarele concepte: -reordonarea citirilor ºi scrierilor - conferã o prioritate mai mare citirilor din memorie faþã de scrierile în memorie, -evitarea citirilor din memorie - eliminã citirile inutile din memorie prin folosirea datelor existente deja în unitatea centralã (în cazul dependenþelor de tipul citire dupã scriere).

Controlul ramificaþiilor, prezicerea ramificaþiilor, dependenþele între date, unitatea în virgulã flotantã, unitatea de interfaþã cu magistrala vor fi prezentate la procesorul 6x86.

Procesorul Cyrix 6x86

Procesorul Cyrix 6x86 este cel mai performant dintre procesoarele de generaþia a ºasea compatibile x86. Îmbunãtãþirea performanþelor este realizatã prin utilizarea unei arhitecturi superscalare, bazate pe o superbandã de asamblare.

Cyrix 6x86 este un procesor superscalar, deoarece conþine douã benzi de asamblare separate ce permit procesarea mai multor instrucþiuni în acelaºi timp. Folosirea unei tehnologii de procesare avansate ºi creºterea numãrului de nivele în benzile de asamblare (superpipelining) permit procesorului 6x86 sã atingã frecvenþe de lucru mai mari de 100MHz.

Prin folosirea caracteristicilor arhitecturale unice, procesorul 6x86 eliminã multe dintre dependenþele între date ºi conflictele la accesarea resurselor, rezultând o performanþã optimã atât pentru programele pe 16 biþi cât ºi pentru cele pe 32 de biþi.

Procesorul Cyrix 6x86 conþine douã cache-uri: -un cache unificat (pentru date ºi pentru instrucþiuni) de 16Ko dual port, ºi -un cache de instrucþiuni de 256 octeþi.

Deoarece cache-ul unificat poate conþine instrucþiuni ºi date în orice raport, acesta oferã o ratã a hit-urilor (numãrul de accese în cache, raportat la numãrul total de accese) mai mare comparativ cu douã cache-uri separate pentru date ºi pentru instrucþiuni, având dimensiuni egale. O creºtere a lãþimii de bandã a transferurilor cache-unitatea întreagã este realizatã prin suplimentarea cache-ului unificat cu un mic cache de instrucþiuni foarte rapid, complet asociativ. Prin includerea acestui cache de instrucþiuni, se evitã conflictele excesive între accesele pentru date ºi pentru cod în cache-ul unificat.

Unitatea în virgulã flotantã din procesor permite executarea instrucþiunilor în virgulã flotantã în paralel cu instrucþiunile întregi. Aceasta conþine o coadã de instrucþiuni pe patru nivele ºi o coadã pentru datele scrise tot pe patru nivele, pentru a facilita execuþia paralelã.

Procesorul 6x86 este alimentat la 3.3V ducând la un consum redus pentru toate frecvenþele de lucru. În plus, 6x86 mai posedã un mod de suspendare pe nivel scãzut, posibilitatea de a întrerupe tactul ºi modul de management al sistemului (SMM) pentru aplicaþiile sensibile la alimentare.

Principalele blocuri funþionale

Procesorul Cyrix 6x86 conþine cinci mari blocuri funcþionale (Fig. 3): -Unitatea întreagã (Integer Unit - IU) , -Unitatea cache (Cache Unit) , -Unitatea de gestionare a memoriei (Memory Management Unit - MMU) , -Unitatea în virgulã flotantã (Floating Point Unit - FPU) , -Unitatea de interfaþã cu magistrala (Bus Interface Unit - BIU).

Instrucþiunile sunt executate în cele douã benzi de asamblare întregi (X ºi Y) ºi în unitatea în virgulã flotantã. Cache-ul conþine cele mai recent utilizate date ºi instrucþiuni pentru a permite accese rapide la informaþii din partea IU ºi FPU.

Adresele fizice sunt calculate de MMU ºi sunt trimise unitaþii cache ºi unitãþii de interfaþã cu magistrala. BIU oferã o interfaþã între placa sistem externã ºi unitaþile interne ale procesorului.

Unitatea întreagã

Unitatea de calcul cu numere întregi oferã o execuþie paralelã a instrucþiunilor în douã benzi de asamblare pentru numere întregi cu ºapte nivele (Fig. 4). Fiecare din cele douã benzi de asamblare (X ºi Y) poate procesa simultan câteva instrucþiuni.

Benzile de asamblare întregi conþin urmãtoarele nivele de prelucrare: -aducerea codului instrucþiunii (Instruction Fetch –IF) , -primul decodificator pentru instrucþiuni (Instruction Decode 1 – ID1) , -al doilea decodificator pentru instrucþiuni (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) , -execuþie (Execute – EX) , -writeback (WB) (Fig. 4).

Nivelul de aducere al codului instrucþiunii (IF) este împãrþit de cele douã benzi de asamblare, aduce câte 16 octeþi de cod din unitatea cache într-un singur ciclu de tact. În acest nivel se cautã orice instrucþiune de salt ce poate apare în fluxul de cod ºi poate afecta secvenþierea normalã a programului. Dacã este detectatã o instrucþiune de salt necondiþionat sau una de salt condiþionat, logica de prezicere a salturilor din acest nivel genereazã o posibilã adresã destinaþie pentru instrucþiunea de salt. Apoi IF aduce codul instrucþiunilor începând cu aceastã adresã.

Funcþia de decodificare a codului instrucþiunii este realizatã de nivelele ID1 ºi ID2. Nivelul ID1, folosit de ambele benzi de asamblare, evalueazã ºirul de octeþi de cod transmis de nivelul IF ºi determinã numãrul de octeþi pentru fiecare instrucþiune. Acest nivel poate trimite cel mult douã instrucþiuni într-un impuls de tact nivelului ID2, câte una pentru fiecare bandã de asamblare.

Cele douã nivele ID2 decodificã instrucþiunile ºi le trimite uneia din cele douã benzi de asamblare X sau Y spre execuþie. Banda de asamblare este aleasã bazatã pe tipul instrucþiunilor aflate deja în fiecare bandã ºi cât de repede se presupune cã se vor termina.

Funcþia de calculare a adreselor este realizatã tot în douã nivele: AC1 ºi AC2. Dacã instrucþiunea are o referinþã la un operand în memorie, AC1 calculeazã o adresã de memorie liniarã pentru instrucþiune.

Nivelul AC2 realizeazã toate funcþiile de gestiunea memoriei cerute, accesele la cache ºi accesele la setul de registre. Dacã AC2 detecteazã o instrucþiune în virgulã flotantã, aceasta este trimisã spre prelucrare unitãþii FPU.

În nivelul de execuþie (EX), se executã instrucþiunile folosind operanzii primiþi din nivelul AC2.

Nivelul writeback (WB) este ultimul din unitatea de lucru cu numere întregi. În acest nivel sunt stocate rezultatele execuþiei sau în registre sau în tamponul de scriere din unitatea cache.

Procesarea în inordine

Dacã o instrucþiune este executatã mai repede decât instrucþiunea precedentã din cealaltã bandã de asamblare, instrucþiunile sunt completate în inordine. Toate instrucþiunile sunt prelucrate în ordine pânã la nivelul EX. În timp ce în nivelele EX ºi WB instrucþiunile pot fi executate în inordine.

Dacã existã dependenþe de date între cele douã instrucþiuni, este necesarã intervenþia unui bloc care sã asigure execuþia corectã a programului. Astfel, chiar dacã instrucþiunile sunt executate în inordine, excepþiile ºi scrierile din cadrul instrucþiunilor sunt întotdeauna efectuate în ordinea cerutã de program.

Selectarea benzii de execuþie

În majoritatea cazurilor, instrucþiunile sunt prelucrate în oricare din cele douã benzi de asamblare ºi nu existã constrângeri cu privire la tipul instrucþiunilor executabile în paralel în cele douã benzi de asamblare. Însã, unele instrucþiuni pot fi prelucrate doar de banda de asamblare X: -instrucþiunile de salt, -instrucþiunile în virgulã flotantã, -instrucþiunile exclusive.

Instrucþiunile de salt ºi cele în virgulã flotantã pot fi executate în paralel cu o altã instrucþiune ce poate fi executatã în banda Y. Instrucþiunile exclusive nu pot fi executate în paralel cu nici o altã instrucþiune. Aceste instrucþiuni necesitã accese multiple la memorie. Chiar dacã aceste instrucþiuni sunt executate exclusiv, este folosit hardware-ul din cele douã benzi de asamblare pentru a se accelera completarea instrucþiunii. În continuare sunt înºirate tipurile de instrucþiuni exclusive ale procesorului 6x86: -încãrcarea segmentelor în modul protejat, -accesele la registrele speciale (registrele de control, debug ºi test) , -instrucþiunile pe ºiruri, -înmulþirea ºi împãrþirea, -accesele la porturile I/O, -PUSHA ºi POPA, -salturile intersegment, apelurile de proceduri ºi ieºirea din proceduri intersegment.

Soluþionarea dependenþelor de date

Când douã instrucþiuni care sunt executate în paralel acceseazã aceeaºi datã sau acelaºi registru, poate apare una din urmãtoarele tipuri de dependenþe de date: -citire dupã scriere (Read-After-Write - RAW) , -scriere dupã citire (Write-After-Read - WAR) , -scriere dupã scriere (Write-After-Write - WAW).

Dependenþele între date în mod normal necesitã serializarea execuþiei instrucþiunilor implicate. Însã, 6x86 implementeazã urmãtoarele trei mecanisme ce permit execuþia paralelã a instrucþiunilor ce conþin dependenþe între date: -redenumirea registrelor (Register Renaming) , -înaintarea datelor (Data Forwarding) , -evitarea datelor (Data Bypassing). În continuare, se vor descrie pe scurt aceste meacnisme.

Redenumirea registrelor

Procesorul Cyrix 6x86 conþine 32 registre fizice de uz general. Fiecare din cele 32 de registre din fiºierul de registre poate fi desemnat a fi unul din registrele de uz general din arhitectura x86 (EAX, EBX, ECX, EDX, ESI, EDI, EBP ºi ESP). Pentru fiecare operaþie de scriere într-un registru este selectat un nou registru fizic, pentru a se reþine temporar ºi data precedentã. Redenumirea registrelor eliminã efectiv toate dependinþele WAW ºi WAR. Pentru programator este transparent acest mod de redenumire a registrelor; este transparent atât pentru sistemul de operare, cât ºi pentru programele aplicaþie.

Exemplul 1. Redenumirea registrelor eliminã dependenþele de tipul scriere dupã citire (WAR). O dependenþã de tip WAR apare atunci când prima dintr-o pereche de instrucþiuni citeºte un registru logic ºi a doua instrucþiune scrie în acelaºi registru. Acest tip de dependenþã este ilustrat de perechea de instrucþiuni de mai jos:

banda X banda Y

(1) MOV BX, AX (2) ADD AX, CX

(BX <- AX) (AX <- AX + CX)

(Ordinea iniþialã din program a instrucþiunilor este arãtatã de numerele din paranteze.)

În absenþa redenumirii registrelor, instrucþiunea ADD din banda de asamblare Y ar trebui sã aºtepte pânã când instrucþiunea MOV din banda de asamblare X ar citi registrul AX.

Însã, procesorul 6x86 evitã blocarea benzii de asamblare într-o astfel de situaþie. Pe mãsurã ce este executatã fiecare instrucþiune, rezultatele sunt plasate într-un nou registru fizic, pentru a evita posibilitatea suprascrierii unei valori a unui registru logic ºi pentru a permite execuþia în paralel a douã instrucþiuni fãrã blocare (fãrã a fi necesarã nici o secvenþiere la accesarea aceleiaºi resurse).

Exemplul 2. Redenumirea registrelor eliminã dependenþele de tipul scriere dupã scriere (WAW)

O dependenþã WAW apare când douã instrucþiuni consecutive realizeazã scrierea în acelaºi registru logic. Acest tip de dependenþã este ilustrat de:

banda X banda Y

(1) ADD AX, BX (2) MOV AX, [mem]

(AX <- AX + BX) (AX <- [mem])

Fãrã denumirea registrelor instrucþiunea MOV din banda de asamblare Y ar trebui sã fie întreruptã pentru a garanta cã instrucþiunea ADD din banda X ºi-a depus rezultatul în AX (Tab.2).

ÃŽnaintarea datelor (Data Forwarding)

Doar redenumirea registrelor, nu poate elimina dependenþele de tipul citire dupã scriere (RAW). 6x86 foloseºte douã tipuri de data forwarding împreunã cu redenumirea registrelor pentru a elimina acest tip de dependenþe: -înaintarea operandului (operand forwarding), - apare când prima dintr-o pereche de instrucþiuni efectueazã o citire din registru sau memorie iar aceastã datã este necesarã celei de-a doua instrucþiuni. CPU executã operaþia de citire ºi furnizeazã data cititã ambelor instrucþiuni; -înaintarea rezultatului (result forwarding) - apare atunci când prima dintr-o pereche de instrucþiuni executã o operaþie (cum ar fi ADD) iar rezultatul ei este citit de o a doua instrucþiune. CPU-ul executã operaþia primei instrucþiuni ºi depune rezultatul operaþiei în destinaþiile ambelor instrucþiuni simultan.

Exemplul 3. Înaintarea operandului eliminã dependenþa de tipul RAW

O dependenþã de tipul RAW apare când prima dintr-o pereche de instrucþiuni realizeazã o scriere iar a doua instrucþiune citeºte acelaºi registru.

banda X banda Y

(1) MOV AX, [mem] (2) ADD BX, AX

(AX <- [mem]) (BX <- AX + BX)

Înaintarea operandului poate apare doar dacã prima instrucþiune nu modificã valoarea iniþialã a datei.

Exemplul 4. Înaintarea rezultatului eliminã dependenþa de tipul RAW

O dependenþã de tipul RAW apare când prima dintr-o pereche de instrucþiuni realizeazã o scriere iar a doua instrucþiune citeºte acelaºi registru.

banda X banda Y

(1) ADD AX, BX (2) MOV [mem], AX

(AX <- AX + BX) ([mem] <- AX)

A doua instrucþiune trebuie sã fie o instrucþiune de transfer iar destinaþia ei poate fi sau un registru sau o locaþie de memorie.

Evitarea datelor (Data Bypassing)

Pe lângã redenumirea registrelor ºi înaintarea datelor, 6x86 conþine o a treia tehnicã de eliminare a dependenþelor de date, denumitã evitarea datelor. Aceasta reduce scãderilor în performanþã ale acelor dependenþe de tipul RAW din memorie ce nu pot fi eliminate cu ajutorul înaintãrii datelor.

Evitarea datelor apare când prima dintr-o pereche de instrucþiuni scrie în memorie ºi urmãtoarea citeºte aceeaºi datã din memorie. 6x86 reþine data din prima instrucþiune ºi o paseazã celeilalte instrucþiuni, astfel eliminându-se un ciclu de citire din memorie.

Exemplul 5. Evitarea datei în dependenþa de tipul RAW

În acest exemplu, dependenþa de tipul RAW apare când prima instrucþiune efectueazã o scriere în memorie iar instrucþiunea urmãtoare citeºte aceeaºi locaþie de memorie.

banda X banda Y

(1) ADD [mem], AX (2) SUB BX, [mem]

([mem] <- [mem] + AX) (BX <- BX - [mem])

Controlul ramificaþiilor

În programe instrucþiunile de salt apar în proporþie de 20-25%. Când fluxul de secvenþiere normalã al programului se schimbã datoritã unei instrucþiuni de salt, nivelele benzilor de asamblare trebuie blocate pânã când CPU-ul calculeazã adresa, aduce ºi decodificã noul flux de instrucþiuni. Procesorul Cyrix 6x86 minimizeazã degradarea în performanþã ºi latenþa introduse de instrucþiunile de salt prin folosirea conceptelor de prezicere a salturilor ºi execuþie speculativã.

Prezicerea salturilor

Procesorul 6x86 foloseºte un tabel al adreselor destinaþie (Branch Target Buffer - BTB) cu 256 de intrãri, set asociativ pe 4 cãi, pentru menþinerea adreselor destinaþie ale instrucþiunile de salt ºi a altor informaþii necesare prezicerii acestor salturi. În timpul aducerii codului instrucþiunii sunt cãutate instrucþiunile de salt în fluxul de instrucþiuni. Dacã este descoperitã o instrucþiune de salt necondiþionat, CPU-ul acceseazã BTB pentru a afla adresa destinaþie a instrucþiunii de salt. Dacã aceastã adresã existã în BTB, CPU-ul începe sã aducã instrucþiunile de la noua adresã.

În cazul salturilor condiþionate, BTB mai menþine o serie de informaþii cu privire la istoricul efectuãrii saltului respectiv (pentru a se putea lua decizia de efectuare sau nu a saltului). Dacã instrucþiunea de salt condiþionat este gãsitã în BTB, 6x86 începe aducerea instrucþiunilor de la adresa prezisã. Dacã instrucþiunea nu este gãsitã în BTB, 6x86 prezice neexecutarea saltului ºi aducerea instrucþiunilor va continua cu adresa urmãtoare. Decizia de efectuare sau nu a saltului este luatã pe baza unui algoritm de prezicere a salturilor.

Odatã ce a fost adus codul unei instrucþiuni de salt condiþionat, aceasta este decodificatã ºi distribuitã spre execuþie benzii de asamblare X. Instrucþiunea trece prin nivelele benzii de asamblare X ºi este terminatã sau în nivelul EX sau în WB, în funcþie de instrucþiunea care a setat indicatorii de condiþii: -dacã instrucþiunea care a setat indicatorii de condiþii este executatã în paralel cu instrucþiunea de salt condiþionat, atunci aceasta este terminatã în nivelul WB, -dacã instrucþiunea care a setat indicatorii de condiþii a fost executatã înaintea instrucþiunii de salt, atunci aceasta se va termina în EX.

Instrucþiunile de salt condiþionat corect prezise se vor executa într-un singur impuls de tact. Dacã dupã terminarea execuþiei instrucþiunii de salt condiþionat s-a detectat o prezicere eronatã a saltului, CPU-ul goleºte benzile de asamblare ºi începe execuþia de la adresa corectã. Procesorul 6x86 în cazul unei instrucþiuni de salt condiþionat aduce în avans atât instrucþiunea prezisã cât ºi cealaltã, dar o trimite benzii de asamblare spre execuþie doar pe cea prezisã. Astfel cã, în cazul unei preziceri eronate, instrucþiunea de la adresa neprezisã nu va mai fi cititã din cache, deoarece a fost adusã deja. Dacã instrucþiunea de salt condiþionat a fost rezolvatã în nivelul EX, atunci întârzierea în cazul unei preziceri eronate este de patru impulsuri de tact, iar dacã instrucþiunea de salt a fost rezolvatã doar în WB, atunci întârzierea este de cinci impulsuri de tact.

Deoarece instrucþiunea de revenire dintr-o subrutinã (RET) este dinamicã, procesorul 6x86 menþine adresele pentru aceste instrucþiuni într-o stivã cu opt intrãri. Adresa de revenire este introdusã în stiva adreselor de revenire de cãtre instrucþiunea CALL, ºi este scoasã de cãtre instrucþiunea RET corespunzãtoare.

Execuþia speculativã

Procesorul 6x86 are posibilitatea de a executa speculativ instrucþiunile urmãtoare unei instrucþiuni în virgulã flotantã sau a unei instrucþiuni de salt. Execuþia speculativã permite benzilor de asamblare sã execute continu instrucþiuni dupã un salt, fãrã a fi necesarã blocarea benzii de asamblare pânã la obþinerea rezultatului execuþiei instrucþiunii de salt condiþionat. Acelaºi mecanism este folosit pentru a se executa instrucþiuni în virgulã flotantã în paralel cu instrucþiunile de numere întregi.

Procesorul are posibilitatea de execuþie în patru nivele de speculaþie. Dupã generarea unei noi adrese prin mecanismul de predicþie, CPU-ul salveazã starea curentã (registrele, indicatorii de condiþii, etc.), incrementeazã numãrãtorul nivelului de speculaþie ºi începe execuþia fluxului de instrucþiuni prezis.

Odatã ce instrucþiunea de salt a fost rezolvatã, CPU-ul decrementeazã nivelul de speculaþie. Pentru un salt corect prezis este ºtearsã starea resurselor salvate la intrarea în nivelul de speculaþie curent. Pentru un salt prezis eronat, procesorul 6x86 genereazã adresa corectã pentru urmãtoarea instrucþiune ºi foloseºte valorile de stare salvate pentru a restaura starea curentã, într-un singur impuls de tact.

Pentru a se menþine compatibilitatea, nu sunt permise scrierile în memorie sau cache, pânã când nu este rezolvatã instrucþiunea de salt. Execuþia speculativã continuã pânã când apare una din urmãtoarele condiþii: -este decodificatã o nouã instrucþiune de salt sau de calcul în virgulã flotantã ºi nivelul de speculaþie este patru (maximul) , -apare o excepþie sau o eroare, -tamponul de scriere este plin, -se încearcã modificarea unei resurse a cãrei stare nu a fost salvatã (registrele segment, indicatorii sistem).

Cache-ul unificat de date ºi instrucþiuni

Procesorul Cyrix 6x86 conþine un cache unificat ºi un cache de instrucþiuni (Fig. 5). Cache-ul unificat cu dimensiunea de 16Ko funcþioneazã ca un cache primar (L1) de date ºi ca un cache secundar (L2) de instrucþiuni. Configurat ca un cache set-asociativ pe patru cãi, conþine pânã la 16Ko de cod ºi date în 512 linii. Cache-ul este dual-port ºi permite executarea a douã din operaþiile urmãtoare în paralel: -citirea unui cod de instrucþiune, -citirea unei date (de cãtre banda X, banda Y sau FPU) , -scrierea unei date (de cãtre banda X, banda Y sau FPU).

Acest cache foloseºte un algoritm de replasare pseudo-LRU (Last Recently Used) ºi poate fi configurat sã aloce o nouã linie de cache doar la un miss de citire, sau ºi la citire ºi la scriere.

Cache-ul de instrucþiuni de 256 octeþi complet asociativ serveºte drept cache de instrucþiuni primar (L1). Cache-ul de instrucþiuni este încãrcat din cache-ul unificat prin magistrala de date internã. Citirile codurilor de instrucþiuni din unitatea pentru numere întregi care se gãsesc în cache-ul de instrucþiuni nu mai acceseazã cache-ul unificat. Dacã instrucþiunea nu este gãsitã în cache-ul de instrucþiuni, linia din cache-ul unificat care conþine instrucþiunea respectivã, este transferatã atât cache-ului de instrucþiuni cât ºi unitãþii pentru numere întregi.

Acest cache foloseºte tot algorimtul de replasare pseudo-LRU. Pentru a se asigura operarea corectã în cazul codului automodificabil, orice scriere în cache-ul unificat este verificatã cu conþinutul cache-ului de instrucþiuni. Dacã a fost modificatã o locaþie care este prezentã ºi în cache-ul de instrucþiuni, atunci linia ce conþine respectiva locaþie este dezactivatã.

Unitatea de gestionare a memoriei

Unitatea de gestionare a memoriei (Memory Management Unit - MMU) a procesorului Cyrix 6x86, prezentatã în Fig. 6, translateazã adresele liniare furnizate de IU într-o adresã fizicã, pentru a putea fi utilizatã în continuare de cache ºi interfaþa cu magistrala. MMU include douã mecanisme de paginare, un mecanism tradiþional ºi un mecanism specific lui 6x86 cu pagini de dimensiuni variabile (Fig. 6).

Mecanismul de paginare cu dimensiunea paginilor variabilã

Acest mecanism de paginare permite programelor sã mapeze pagini cu dimensiunea între 4Ko ºi 4Go. Folosirea paginilor de dimensiuni mari poate duce la sporirea performanþei unor anumite aplicaþii.

Mecanismul tradiþional de paginare

Mecanismul tradiþional de paginare a fost îmbunãtãþit la 6x86 prin adãugarea unui cache pentru tabelul directorilor (Directory Table Entry -DTE) ºi un TLB victimã. TLB-ul principal este cu mapare directã ºi conþine 128 de intrãri pentru tabelul paginilor. Cache-ul DTE cu patru intrãri complet asociative conþine accesele cele mai recente la DTE.

TLB-ul victimã conþine liniile din TLB principal care au fost înlocuite datoritã unui miss în TLB. Dacã se face referirea la o paginã ce are PTE-ul în TLB-ul victimã, linia aceasta este schimbatã cu o linie din TLB-ul primar.

Unitatea în virgulã flotantã

Interfaþa dintre unitatea în virgulã flotantã (FPU) a procesorului 6x86 ºi unitatea pentru numere întregi este realizatã printr-o magistralã internã pe 64 de biþi. Setul de instrucþiuni FPU al procesorului 6x86 este compatibil x87 ºi aderã standardului IEEE-754.

Procesorul Cyrix 6x86 executã instrucþiunile întregi în paralel cu instrucþiunile în virgulã flotantã. Instrucþiunile întregi pot fi executate în inordine cu respectarea instrucþiunilor FPU.

Aºa cum s-a mai spus, instrucþiunile FPU sunt întotdeauna executate în banda de asamblare X. Nivelul pentru calculul adresei din banda X verificã apariþia excepþiilor de gestionare a memoriei ºi acceseazã operanzii din memorie folosiþi de FPU. Dacã nu apare nici o excepþie, se salveazã starea curentã a procesorului în AC2 ºi trimite instrucþiunea în virgulã flotantã spre execuþie FPU-ului. Apoi unitatea centralã poate executa orice instrucþiune întreagã urmãtoare, speculativ ºi în inordine.

Unitatea centralã 6x86 poate trimite pânã la patru instrucþiuni FPU în coada de aºteptare a FPU. CPU-ul continuã cu execuþia speculativã ºi în inordine pânã când apare una dintre condiþiile ce cauzeazã oprirea execuþiei speculative. Pe mãsurã ce FPU terminã de executat o instrucþiune în virgulã flotantã, este decrementat nivelul speculativ ºi sunt ºterse valorile de stare salvate la începutul acestei instrucþiuni. Unitatea în virgulã flotantã mai conþine ºi un set de patru tampoane de scriere pentru a preveni întreruperile datorate scrierilor speculative.

Procesoarele Cyrix 6x86MX ºi MII

Aceste procesoare au la bazã nucleul procesorului 6x86, îmbunãtãþit cu cele 57 instrucþiuni multimedia noi, compatibile cu tehnologia MMX. În plus, 6x86MX ºi MII lucreazã la frecvenþe mai mari, conþin un cache de dimensiune mai mare, un tampon destinat translatãrii adreselor liniare în adrese fizice (TLB) pe douã nivele ºi un cache destinat adreselor de salt îmbunãtãþit (Fig. 7).

Pentru a oferi suportul pentru operaþiile multimedia, cache-ul poate fi transformat într-o memorie RAM scratchpad. Aceastã memorie funcþioneazã ca o memorie privatã pentru CPUºi nu participã în operaþiile cache

Pânã unde se poate merge în direcþia miniaturizãrii ºi creºterii performanþelor?

O privire asupra dezvoltãrii procesoarelor de la origini pânã în prezent ne poate permite sã caracterizãm arhitecturile microprocesoarelor contemporane ºi chiar sã încercãm sã prevedem cum vor aratã cele de mâine.

Am întâlnit de mai multe ori un banc pe Internet, care spunea cã, dacã maºinile ar fi evoluat în aceeaºi mãsurã cu calculatoarele, acum ar fi mers 120 de kilometri cu benzina dintr-o brichetã ºi ar fi costat cât o pâine. Pe de altã parte, un contra-banc, din partea industriei automobilistice, ofensate, zicea apoi cã, dacã ar fi evoluat la fel, maºina ar fi refuzat sã mai meargã de câteva ori pe zi, ºi ar fi trebuit sã o duci înapoi în garaj ca sã reporneascã.

Adevãrul este cã progresele fãcute de tehnologia calculatoarelor sunt absolut uluitoare; ajunge sã îþi cumperi un calculator nou dupã doi ani ca sã fii impresionat de câºtigul de performanþã înregistrat. Sporul de performanþã se datoreazã unor procesoare din ce în ce mai sofisticate ºi mai rapide, ºi unor memorii de capacitãþi din ce în ce mai mari.

Rãspunzãtoare pentru creºterea exponenþialã a performanþei sunt însã în cea mai mare mãsurã microprocesoarele. În acest articol vom arunca o privire asupra evoluþiei microprocesoarelor de la origini pânã în prezent. Vom încerca apoi sã caracterizãm arhitecturile procesoarelor contemporane ºi sã extrapolãm din datele la dispoziþie, speculând despre unele din posibilele evoluþii viitoare.

Trebuie sã atrag de la început atenþia cã nu am însuºiri paranormale ºi, ca atare, nu sunt profet. Domeniul tehnologiilor de calcul este extraordinar de volatil ºi se miºcã cu o vitezã fantasticã; orice previziune este cel puþin hazardatã. De altfel caseta "Performanþe - estimãri" ilustreazã acest fapt, contrapunând previziunile din urmã cu câþiva ani ale unei organizaþii extrem de prestigioase, Semiconductor Industry Association (SIA, http://www.semichips.org/), cu realitatea. Deci nu vã aºteptaþi de la mine la mai mult.

Am mai publicat în PC Report o serie întreagã de articole despre arhitectura procesoarelor moderne, pe care le voie cita ocazional; toate acestea sunt disponibile din pagina mea de web. Articolul de faþã va fi însã mai superficial. Existã o cantitate enormã de informaþie pe web. În acest articol am folosit în mod repetat informaþii de la http://bwrc.eecs.berkeley. edu/CIC/, CPU Info Center.

Aspecte economice

Un istoric interesant al diferitelor idei arhitecturale din microprocesoare puteþi gãsi pe web la http://bwrc.eecs.berkeley.edu/CIC/archive/ cpu_history.html.

Primul microprocesor a fost creat de firma Intel în 1971. Numele sãu era Intel 4004, ºi era un procesor pe 4 biþi. Apariþia primului microprocesor a fost un pas cu uriaºe consecinþe în evoluþia ulterioarã a sistemelor de calcul. Diferenþa între microprocesor ºi metodele îndeobºte folosite era cã procesorul strânge pe o singurã pilulã de siliciu toate unitãþile funcþionale importante necesare executãrii programelor; fiind toate strâns integrate, comunicaþia între ele este rapidã ºi eficace, permiþând dintr-o datã un salt calitativ.

Nu mai puþin importantã este reducerea de cost care urmeazã unei astfel de integrãri. Cu siguranþã cã principalul motiv al evoluþiei explozive a tehnologiei circuitelor integrate nu este de naturã tehnologicã, ci economicã: spirala preþurilor din ce în ce mai scãzute face echipamentele de calcul din ce în ce mai accesibile, cererea creºte, ducând la venituri mai ridicate pentru fabricanþi, care investesc mai mult în cercetare/dezvoltare ºi linii tehnologice, obþinând densitãþi mai mari, permiþând integrarea mai multor circuite precum ºi costuri ºi mai scãzute. Cu toatã scãderea de preþ, veniturile globale ale industriei semiconductoarelor au crescut în mod galopant: numai anul trecut vânzãrile globale au fost de 149 de miliarde de dolari!

Esenþial pentru a menþine aceastã spiralã este faptul cã echipamentele de calcul mãresc enorm productivitatea muncii, direct sau indirect: de aici cererea crescândã. Iar experþii afirmã cã acesta este doar începutul ºi cã în viitor fiecare individ va depinde de zeci de dispozitive de calcul în fiecare clipã. Nu suntem prea departe de acest punct: chiar în ziua de azi, o maºinã modernã are în medie 15 microprocesoare, care controleazã, regleazã ºi diagnosticheazã tot felul de parametri, de la injecþie pânã la frâne.

Nu pot sã mã abþin sã remarc cã Statele Unite ale Americii atribuie o treime din creºterea venitului naþional brut în anul trecut doar tehnologiilor informaþionale, care însã ocupã doar 8% din forþa de muncã. În foarte mare mãsurã, tehnologia informaþiei este responsabilã pentru fenomenala dezvoltare economicã pe care Statele Unite o traverseazã în aceºti ani.

Aspecte cantitative

Sã lãsãm acum deoparte economia, ºi sã aruncãm o privire asupra evoluþiei unor parametri ai procesoarelor de-a lungul timpului. Tabela "Cronologia Intel" prezintã evoluþia generaþiilor succesive ale celei mai proeminente familii de procesoare, ale firmei Intel.

Ultima coloanã din tabel ºi figura "Performanþe - estimãri" aratã care este impactul miniaturizãrii: aceastã coloanã indicã dimensiunea de bazã (feature size), care poate fi vãzutã ca fiind dimensiunea unui tranzistor. Orice reducere a acestei valori are un impact cvadratic, pentru cã suprafaþa creºte cu pãtratul laturii. O reducere de la 2 microni la 1,5 (50%) mãreºte deci suprafaþa efectivã cu 77% (4/2,25 = 1,77).

Din fericire, reducerea dimensiunilor mai are încã o consecinþã foarte importantã: traseele pe care trebuie sã le parcurgã curentul electric între dispozitive devin mai scurte, deci se pot parcurge mai rapid. Proiectanþii pot face deci procesorul sã funcþioneze cu un ceas mai rapid.

Observaþie: Majoritatea covârºitoare a procesoarelor contemporane funcþioneazã în mod sincron: întreaga lor funcþionare este orchestratã de un tact de ceas, care garanteazã cã feluritele pãrþi sunt sincronizate. Din ce în ce mai mult însã se tinde spre scheme cu multiple semnale de ceas, sau chiar scheme asincrone. Nu ne vom ocupa însã de aceste evoluþii în textul acestui articol.

Faptul cã avem siliciu la dispoziþie pentru a implementa mai mulþi tranzistori înseamnã cã:

1). Putem muta mai multe circuite auxiliare pe acelaºi cip. Evoluþia procesoarelor cunoaºte câteva salturi calitative: când miniaturizarea fãcea posibilã integrarea unui nou dispozitiv pe acelaºi circuit integrat, se realiza un salt de performanþã. Astfel, au fost integrate succesiv: unitãþi din ce în ce mai mari de procesare (8, 16, 32, acum 64 de biþi), coprocesoare aritmetice, unitãþi de management al memoriei, cache-uri de nivel 1 ºi chiar 2;

2). Designerii folosesc tranzistorii suplimentari pentru a construi circuite mai sofisticate, care pot executa mai repede ºi mai eficient programele. Metoda fundamentalã folositã este de a face mai multe lucruri în paralel.

Împreunã aceste trei fenomene (viteza ceasului, integrarea pe o singurã pastilã ºi exploatarea paralelismului) contribuie la creºterea performanþei totale a procesoarelor. Aºa cum am povestit ºi cu alte ocazii, mãsurarea performanþei unui calculator se face evaluând sistemul pe mai multe programe (deci performanþa depinde foarte mult ºi 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, http:// www.specbench.org). Nu ne va interesa acum prea tare ce reprezintã numerele acestea; cert este cã cu cât sunt mai mari, cu atât e mai bine. Graficul din figura "Performanþe - SPEC" aratã evoluþia performanþei procesoarelor în ultimii 10 ani, în termeni SPEC.

Evoluþia urmãreºte aproximativ o curbã exponenþialã: în fiecare an performanþa creºte cu 60%.

Tehnologii arhitecturale

Aºa cum am ilustrat în seria mea de articole intitulate "Arhitectura avansatã a procesoarelor", o mulþime de inovaþii tehnologice au fost introduse una dupã alta în arhitecturi; de fapt intenþionez sã continui aceastã serie ºi în viitor, pentru cã mai sunt de prezentat ºi alte mecanisme importante.

Îmi permit sã prezint în continuare viziunea profesorului John Hennessy, de la universitatea Stanford, aºa cum a expus-o în prelegerea pe care a þinut-o ca invitat la Federated Computer Research Conferences, în mai 1999.

Hennessy vede douã tehnologii arhitecturale ca fiind esenþiale: exploatarea paralelismului la nivel de instrucþiune (Instruction Level Parallelism, ILP) ºi ierarhii sofisticate de memorie (cache-uri). Sã spunem câteva cuvinte despre fiecare:

ILP

Paralelismul la nivel de instrucþiune constã în independenþa instrucþiunilor din programe una de alta, ceea ce ne permite sã executãm mai multe instrucþiuni simultan. Am vorbit altãdatã pe larg despre paralelismul la nivel de instrucþiune; sã observãm cã toate procesoarele contemporane îl exploateazã prin douã forme:

Execuþia pe bandã de asamblare (pipeline) a instrucþiunilor succesive;

Execuþia în paralel a instrucþiunilor independente: procesoarele de tip VLIW (very long instruction word) aleg la compilare care instrucþiuni merg în paralel, iar procesoarele superscalare fac aceastã alegere în timpul execuþiei.

Astfel, în 1985 au apãrut primele procesoare cu banda de asamblare, în 1990 primele procesoare de tip VLIW, iar în 1995 procesoare foarte sofisticate superscalare, care pot executa instrucþiunile în ordini foarte diferite de cea din program (out-of-order execution).

Cache-uri

Am scris în repetate rânduri despre cache-uri în PC Report (de pildã martie 1997 ºi noiembrie 1998). Aici vom arunca doar o privire superficialã asupra lor; scopul nostru este de a înþelege de ce cache-urile joacã un rol fundamental în creºterea performanþei. Figura "Performanþe - memorii ºi procesoare" ne oferã cheia: deºi atât procesoarele cât ºi memoriile cresc constant în vitezã, creºterea procesoarelor este cu 50% mai rapidã decât a memoriilor. Ca atare existã o disparitate crescândã între nevoile de date (ºi instrucþiuni) ale procesorului ºi ceea ce memoriile pot oferi. Durata unui acces la memorie ajunge la zeci de cicli de ceas pentru procesoarele contemporane. Întârzierea accesului este ºi mai exacerbatã în cazul sistemelor care au mai multe procesoare, în care caz timpii de acces la date pot ajunge la mii de cicli.

Din aceastã cauzã se construiesc cache-uri, care sunt memorii mai mici ºi mai rapide, care se plaseazã între procesor ºi memoria principalã, ºi în care sunt aduse datele pentru prelucrare. Proiectanþii au reuºit sã sporeascã eficacitatea cache-urilor folosind douã metode:

(a) Prin folosirea unor cache-uri din ce în ce mai mari, plasate din ce în ce mai aproape de procesor. Aceastã evoluþie este clar vizibilã:

Primele procesoare nu aveau nici un fel de cache, pentru cã memoriile erau suficient de rapide pentru a le servi cu date. În 1980 au apãrut cache-uri (L1) sub forma unor circuite speciale, care în 1984 au fost integrate pe aceeaºi pilulã de siliciu cu procesorul central, dupã care (1986) a apãrut un al doilea nivel de cache (L2), mai mare ºi ceva mai lent, care în procesoarele moderne (1995) este la rândul lui adesea integrat cu circuitul microprocesorului, pentru a permite un acces rapid. Au apãrut nivele terþiare de cache (1999).

(B) Pe de altã parte metodele de management ale cache-urilor sunt din ce în ce mai sofisticate:

Au apãrut cache-uri care servesc procesorul de îndatã ce primul cuvânt a sosit, chiar dacã restul sunt pe drum (early restart, 1992), cache-uri care nu blocheazã procesorul când datele lipsesc, ci îi permit sã continue execuþia (non-blocking, 1994) ºi tot felul de alte tehnologii sofisticate, pe care le-am expus în alte pãrþi (cache-uri victimã, buffere de scriere, instrucþiuni speciale (prefetching) de management al cache-ului etc.). Tot aici se cuvine sã menþionãm multiprocesoarele simetrice ºi protocoalele de coerenþã ale cache-urilor pentru astfel de sisteme; toate procesoarele moderne sunt construite pentru a fi folosite în sisteme multi-procesor, ºi includ astfel de dispozitive.

Arhitecturile contemporane

Astfel, urmãrind evoluþia arhitecturilor, am ajuns pânã în ziua de azi. Vom încerca sã caracterizãm sumar starea arhitecturilor, dupã care vom arunca o privire asupra unora din direcþiile viitoare.

Hardware ºi software. Istoria modernã a procesoarelor contrapune douã paradigme pentru creºterea performanþei, bazate pe software ºi respectiv pe hardware. Aparent, un articol despre arhitectura procesoarelor nu are nimic de-a face cu softul. Nimic mai greºit: la ora aceasta existã o simbiozã totalã între hardware ºi software. Procesoarele se proiecteazã odatã cu compilatoarele care le folosesc iar relaþia dintre ele este foarte strânsã: compilatorul trebuie sã genereze cod care sã exploateze caracteristicile arhitecturale, altfel codul generat va fi foarte ineficace.

Metodele de creºtere a performanþei cu ajutorul compilatoarelor se numesc ºi statice, pentru cã programul este analizat ºi optimizat o singurã datã, înainte de a fi pornit în execuþie. Metodele bazate pe hardware se numesc dinamice, pentru cã sunt aplicate în timp ce programul se executã.

Istoria arhitecturilor contrapune mereu cele douã paradigme: de exemplu dezbaterea iniþialã RISC/CISC era de aceeaºi naturã, ca ºi dezbaterea între superscalar ºi VLIW, pe care am menþionat-o deja în acest text.

Notã: În anii '80 a apãrut ideea de a face procesoarele mult mai simple pentru a le permite sã meargã mai repede. Astfel de arhitecturi au fost numite RISC: Reduced Instruction Set Computer, prin contrast cu celelalte, Complex ISC.

De fapt, aºa cum menþionam ºi în alte articole (de exemplu în PC Report din iunie 1999), existã lucruri care se pot face numai static ºi existã lucruri care se pot face numai dinamic. Aºa cã de fapt, chiar arhitecturile care pornesc la una din extreme, tind sã conveargã cãtre folosirea unui amestec de trãsãturi din ambele domenii:

La ora actualã distincþia RISC/CISC aproape cã s-a estompat. De exemplu, Pentium, un procesor tipic CISC, de fapt traduce în mod automat instrucþiunile în instrucþiuni de tip RISC în hardware, dupã care le executã. Pe de altã parte, toate procesoarele RISC au cãpãtat extensii la setul de instrucþiuni (gen CISC) pentru a le mãri eficacitatea; de pildã toate procesoarele au extensii speciale pentru multimedia.

De asemenea, graniþele dintre super-scalar ºi VLIW tind sã se estompeze, fiecare împrumutînd din tehnologiile celuilalt.

Cu siguranþã cã un model mixt este preferabil, pentru cã poate lua ce e mai bun din fiecare tehnologie.

Crusoe

Se cuvine sã atragem atenþia asupra unei recrudescenþe a "luptei" sistemelor pure: anul acesta compania Transmeta a anunþat apariþia unui nou procesor, numit Crusoe, care exploateazã la maximum tehnologiile statice (compilarea). Compania Transmeta a fãcut mare vâlvã, nu atât prin procesorul lor, care poate simula alte procesoare, inclusiv cele ale firmei Intel, ci prin faptul cã angajeazã pe cel mai faimos programator al planetei, Linus Torvalds, creatorul sistemului de operare Linux.

Transmeta a lansat Crusoe cu mare pompã în luna ianuarie; compania predicã întoarcerea la simplitate (care a fost sugeratã atât de curentul RISC, cât ºi de modelele VLIW), în care hardul este simplu ºi rapid iar compilatorul duce greul. Echipa care a lucrat la Transmeta este compusã în mare mãsurã din ingineri plecaþi de la IBM: IBM a lucrat la o versiune de procesor PowerPC care putea face exact acelaºi lucru: putea executa în mod nativ cod x86 (adicã compatibil Intel), dar proiectul lor a fost întrerupt deºi era într-o stare foarte avansatã, aparent din motive de marketing.

Cât de serios este acest nou competitor?

Din pãcate atuurile lui Crusoe nu sunt prea clare:

• cipul nu are un ceas mai rapid decât procesoarele Intel (versiunile de Crusoe disponibile acum merg doar la 400Mhz, comparativ cu Pentium, care ajunge la 800);

• cipul într-adevãr consumã mult mai puþinã energie ºi are nevoie de mult mai puþinã rãcire. Transmeta afirmã cã asta-l face ideal pentru laptop-uri. Din pãcate, principalul consumator de energie într-un laptop nu este procesorul, ci ecranul ºi discul, aºa încât avantajele noului cip vor fi marginale;

• Crusoe se bucurã de compatibilitate cu setul de instrucþiuni x86; dar pentru platformele pe care x86 este dominant (desktop, laptop, chiar ºi server) am vãzut cã performanþa lui este insuficientã. Dacã Crusoe vrea sã concureze pentru celelalte pieþe, de procesoare integrate (embedded computing), atunci are de-a face cu alþi competitori formidabili, ca procesoarele de semnal de la Motorola, Texas Instruments ºi Intel (ARM), asupra cãrora nu este clar câte avantaje are.

Probabil cã pentru a rãmâne viabil, Crusoe va trebui sã se metamorfozeze ºi sã devinã mai complicat, folosind ºi o serie de mecanisme dinamice de creºtere a performanþei.

În definitiv existã o singurã resursã aproape gratuitã ºi care este în cantitãþi suficiente: numãrul de tranzistori. Datoritã miniaturizãrii numãrul de tranzistori disponibili pentru design creºte enorm; de aceea simplitatea cu orice preþ (aºa cum o încarneazã Crusoe) nu este neapãrat o calitate.

Constrângerile fizice

Proiectanþii de microprocesoare se lovesc în ziua de azi de mai multe dificultãþi. Nici una dintre ele nu e insurmontabilã, dar soluþiile sunt din ce în ce mai grele. Vom arunca o privire asupra unora dintre ele; încercarea de a extrapola impactul acestor bariere în viitor va sugera apoi soluþii pentru depãºirea lor.

Accesul la memorie

Dupã cum am vãzut în figura "Performanþe - memorii ºi procesoare", în ultimii 10 ani viteza memoriilor a crescut cu 10% pe an, în timp ce viteza procesoarelor a crescut cu o rata de 60%. Toate motivele ne îndeamnã sã credem cã aceastã disparitate va continua sã se accentueze, ºi cã preþul relativ al unui acces la memorie (mãsurat în cicli de ceas) va continua sã creascã.

Putere

Un alt factor care limiteazã evoluþia circuitelor integrate este consumul de putere; în urmã cu 15 ani un procesor consuma 2 waþi; astãzi un procesor ca Alpha 80364 consumã 100W; de aici rezultã limitãri pentru ceas (puterea consumatã creºte cu frecvenþa ceasului), ºi necesitatea unor dispozitive speciale de rãcire.

Din fericire tehnologia lucreazã în direcþia favorabilã: miniaturizarea duce la scãderea puterii necesare. Un alt factor care duce la scãderea puterii consumate este scãderea tensiunilor de alimentare.

Interesant este faptul cã, deºi dimensiunea tranzistorilor a scãzut într-una, dimensiunile circuitelor fabricate au crescut: foamea neostoitã a designerilor cere suprafeþe din ce în ce mai mari ale plãcuþelor de siliciu; de aceea puterea consumatã a crescut ºi ea.

Complexitate

Un factor deloc neglijabil este complexitatea enormã a circuitelor. Procesoarele cele mai moderne au peste 25 de milioane de tranzistoare, iar în câþiva ani designerii vor avea la dispoziþie un miliard. Astfel de circuite sunt foarte greu de verificat ºi testat. La ora actualã o companie ca Intel cheltuieºte 40% din budget pentru proiectare ºi dezvoltare, ºi 60% pentru verificare ºi testare!

O altã problemã importantã este legatã de liniile tehnologice de fabricaþie: o astfel de instalaþie costã la ora actualã douã miliarde de dolari. Puþine companii îºi pot permite investiþii de asemenea anvergurã pentru o tehnologie care se schimbã în 3 ani!

Sârmele

E clar cã miniaturizarea nu va putea continua în acelaºi ritm exponenþial: peste ceva vreme am ajunge la necesitatea de a face un tranzistor mai mic decât un atom, ceea ce e evident imposibil. Dar chiar înainte de a atinge un astfel de prag, vom avea alte probleme de înfruntat.

O analizã extrem de interesantã a fost fãcutã de Mark Horowitz, profesor la universitatea Stanford, într-un articol intitulat "Viitorul sârmelor". Articolul porneºte de la caracteristicile electrice ale semiconductorilor ºi analizeazã o serie de scenarii posibile pentru tehnologiile de fabricaþie. Textul ia în considerare tot felul de factori, cum ar fi geometria sârmelor, capacitãþi ºi rezistenþe, disiparea puterii etc. Vom ignora toate aceste detalii, însã vom privi una din concluziile la care autorul ajunge.

Autorul observã cã în general sârmele vor evolua în sensul dorit: vor deveni mai scurte, iar viteza de transmisiune a informaþiei nu va scãdea, relativ la dimensiunea circuitului. Deci dacã am lua un microprocesor de astãzi ºi l-am reduce la scarã, sârmele nu ar constitui un impediment în funcþionarea sa corectã.

Problema apare însã din faptul cã de fapt suprafaþa circuitelor nu scade, din cauzã cã designerii adaugã noi module. O mare problemã sunt sârmele care traverseazã mai multe module. Lungimea acestora rãmâne practic constantã, în milimetri. Ori, cum viteza ceasului creºte mereu, asta înseamnã cã semnalele electrice nu mai au timp sã parcurgã sârmele de la un capãt la altul. La 1Ghz, lumina strãbate în vid 30 de centimetri. Dar viteza luminii în solide este mai micã iar viteza de propagare scade semnificativ odatã cu numãrul de "consumatori" ai sârmei (adicã o sârmã conectatã la 3 circuite e mult mai lentã decât una cuplatã la doar douã). De asemenea, liniile lungi de transmisiune vor avea nevoie de amplificatoare, care încetinesc substanþial semnalul.

Asta înseamnã cã circuitele viitorului nu vor mai putea comunica prin semnale globale: pur ºi simplu va fi imposibil pentru o sârmã sã uneascã diferitele pãrþi ale circuitului. Aceasta este o consecinþã de cea mai mare importanþã pentru arhitecturile viitoare!

Zgomotul

În fine, pe mãsurã ce tranzistorii sunt mai mici, sârmele sunt mai subþiri ºi consumul de putere este mai mare, circuitele sunt mai sensibile la zgomot, fie el termic, din mediu (de exemplu radiaþii cosmice) sau, în curând, chiar efecte cuantice! Fenomenele de transport din semiconductori pe care se bazeazã tranzistorul sunt fenomene statistice: or, când dimensiunile devin atât de mici încât numai câþiva electroni produc semnalele, statistica nu mai opereazã iar excepþiile încep sã aparã.

Generaþia urmãtoare

În aceastã ultimã secþiune vom încerca sã discernem ce ne oferã viitorul. Marile companii lucreazã simultan la mai multe generaþii ale unui procesor, cu echipe independente, ca atare ceva din ceea ce viitorul ne rezervã poate fi observat în produsele comerciale în curs de proiectare, în mãsura în care companiile dezvãluie astfel de informaþii.

Cercetarea în arhitectura procesoarelor este efervescentã, atât în industrie cât ºi în universitãþi; este absolut imposibil de urmãrit întregul peisaj. Iatã însã unele dintre direcþii:

Evoluþie incrementalã

Un efort substanþial este în continuare depus în a perfecþiona tehnicile care în ultimii 15 ani au servit atât de bine arhitectura, pe care le-am descris mai sus: exploatarea paralelismului la nivel de instrucþiune ºi ierarhiile de memorie.

Iatã unele dintre tendinþe:

Trace cache: este un cache pentru instrucþiuni care, în loc de a pãstra instrucþiunile în ordinea adreselor lor, le menþine în ordinea în care este probabil sã fie executate.

Execuþia speculativã ºi predicþia valorilor: într-un articol anterior din PC Report (din iulie 1999) am vãzut cã principala limitare în calea execuþiei paralele a instrucþiunilor sunt dependenþele între instrucþiuni: una are nevoie de rezultatul alteia pentru a se executa. Or, dacã prima instrucþiune dureazã mult, atunci a doua nu se poate executa nici ea. Soluþia ades folositã este de a ghici valoarea rezultatã ºi de a executa ºi instrucþiunea dependentã. Când rezultatul primei instrucþiuni soseºte, este comparat cu cel ghicit (prezis); dacã predicþia a fost corectã, toate sunt bune, altfel instrucþiunea dependentã este re-executatã. Existã felurite forme de predicþie a valorilor, unele folosite deja de multã vreme (cum ar fi predicþia salturilor, pe care am descris-o în PC Report din august 1999), dar este plauzibil ca scheme din ce în ce mai sofisticate sã-ºi facã apariþia.

Execuþia predicatã, care este deja folositã de procesoare de prelucrare de semnal ca Texas Instruments C6X, ºi care va fi una din trãsãturile fundamentale ale noii arhitecturi de la Intel, Merced. Execuþia predicatã evitã execuþia instrucþiunilor de salt (care au un efect negativ asupra performanþei, aºa cum am arãtat în articolul mai sus-citat) ºi preferã sã execute instrucþiuni în mod inutil dupã care sã arunce rezultatele la gunoi (de exemplu, când avem o structurã de genul if-then-else, o arhitecturã predicatã poate executa ambele ramuri ale condiþiei, dar va permite numai uneia dintre ele sã-ºi facã efectele vizibile).

Multi-procesoare

Aºa cum am vãzut, proiectanþii tind sã înghesuie din ce în ce mai multe circuite pe aceeaºi pilulã de siliciu. O evoluþie naturalã este de a face saltul de la mai multe procesoare legate printr-o magistralã comunã (ca în cazul sistemelor cu multiprocesoare simetrice, pe care le-am descris în PC Report din noiembrie 1998) în procesoare strâns cuplate, pe aceeaºi pilulã de siliciu.

De fapt, astfel de scheme existã deja: procesorul pentru mainframes IBM S/390 are douã nuclee identice, care executã sincron acelaºi program: în cazul în care rezultatele nu sunt identice se executã o excepþie ºi programul este reluat. Acesta este un exemplu în care mai multe resurse sunt folosite pentru o fiabilitate sporitã, dar IBM a anunþat cã viitorul lor procesor G5 va conþine douã nuclee independente pe aceeaºi pilulã, permiþând realizarea unor sisteme multi-procesor cu un singur cip.

Multithreading

O evoluþie naturalã ar fi spre a exploata alte forme de paralelism decât cel la nivel de instrucþiune (ILP). Calculatoarele moderne exploateazã excelent paralelismul la nivel de proces, dar existã forme intermediare, ºi trebuie sã ne aºteptãm sã vedem arhitecturi din ce în ce mai orientate spre acestea:

• Paralelism la nivel de buclã: în care iteraþii succesive ale unei bucle sunt executate în paralel.

• Paralelism la nivel de thread; despre multithreading am scris un articol amplu în PC Report din ianuarie 1997.

Existã o sumã de inovaþii arhitecturale legate de aceste tehnologii, încã ne-integrate în produse comerciale. Sã privim cîteva dintre ele:

• Thread-level data speculation: este o metodã de a implementa paralelismul la nivel de buclã, lansând câte un thread pentru fiecare iteraþie a buclei. De exemplu, proiectul STAMPede de la Universitatea Carnegie Mellon, condus de profesorul Todd Mowry exploreazã aceastã alternativã (http://www.cs.cmu.edu/ ~tcm/STAMPede.html).

• Simultaneous multi-threading, propus la universitatea din Seattle în 1995. Aceastã tehnologie menþ

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...