Ce limbi vorbeste?
O alta caracteristica a lui Prescott (dar si a altor procesoare din familia P4) este HyperThreading-ul. Acesta reprezinta, în esenta, un set de instructiuni capabil sa simuleze functionarea procesorului în mod dual, software-ul comportându-se ca si cum în sistem ar fi prezent, fizic, un al doilea CPU. S-a dovedit faptul ca doua sarcini diferite, cum ar fi doua aplicatii sau doua thread-uri (ramuri) ale aceleiasi aplicatii lucreaza mai rapid în acest mod, cu un minim de suport atât hardware cât si software, motivul fiind faptul ca multe zone ale procesorului nu sunt folosite la adevaratul potential când executa o singura sarcina. De aceea, Intel a implementat tehnologia HyperThreading în ultimele procesoare Northwood, precum si în majoritatea modelelor de Prescott. Însa sporul maxim de viteza se obtine doar atunci când aplicatiile sunt optimizate pentru acest mod de lucru, în caz contrar putând fi sesizate chiar si scaderi de performanta. Desi aceasta tehnologie nu este specifica doar lui Prescott, am descris-o pentru a putea fi înteles paragraful urmator. De remarcat însa ca exista versiuni de Prescott fara aceste instructiuni.
În 1997, Intel a introdus instructiunile MMX (MultiMedia eXtensions), cu scopul de a accelera aplicatiile multimedia optimizate pentru acestea. MMX a fost extins cu SSE (Streaming SIMD Extensions), apoi cu SSE2 odata cu Pentium 4 iar Prescott a introdus SSE3, ce cuprinde un numar mic de instructiuni în comparatie cu precedentele versiuni, nefiind decât o completare a acestora. Nu este deloc o exagerare sa afirmam ca SSE3 contine ceea ce Intel a uitat sa implementeze în SSE si SSE2. SSE3 ofera avantaje minore diverselor sarcini ale aplicatiilor multimedia, cum ar fi compresia video. Pe lânga cele 11 instructiuni diverse, destinate operatiilor cu numere complexe, conversiei integer-FPU si altele, ultimele doua optimizeaza modul de operare HyperThreading dar necesita suport din partea sistemului de operare. Asteptam cu interes dezvoltarea software-ului care sa profite de SSE3, Intel punând la dispozitie versiunea a opta a compilatorului propriu de C++, care „stie” de SSE3. Sporul de performanta adus ar putea atinge 10 procente, SSE3 nefiind altceva decât unul din numeroasele avantaje minore ale lui Prescott, însa sub care daca tragem linie obtinem ceva remarcabil. Asta daca ar fi vorba doar de avantaje...
Conductele
Poate cel mai important aspect legat de noul Prescott este dat de pipeline (în traducere - conducta). Acesta reprezinta suma unor etape pe care instructiunile trebuie sa le parcurga pâna la obtinerea rezultatului final. Pipeline-ul este împartit în stagii, fiecare având o sarcina bine definita. Iata un exemplu de pipeline simplu, fiecare stagiu ocupând exact timpul unui ciclu de tact.
stagiul 1: fetcher – pregateste urmatoarea instructiune
stagiul 2: decoder – decodifica urmatoarea instructiune
stagiul 3: ALU – executa instructiunea
stagiul 4: retire unit – aduce rezultatul înapoi în memorie
Desigur, toate aceste operatii puteau fi executate neorganizat, însa pentru un pipeline cu patru stagii avem patru operatii care sunt realizate simultan în locul uneia singure. Si nu trebuie înteles faptul ca fiecare pipeline este legat de aceeasi instructiune, ci dimpotriva. Spre exemplu, fetcher-ul pregateste instructiunea de desenare a unei ferestre, decoder-ul este ocupat cu decodificarea unei instructiuni de desenare a unui caracter în acea fereastra, ALU-ul calculeaza pozitia icon-ului în interiorul ferestrei iar retire unit-ul returneaza memoriei rezultatul copierii unor fisiere în background. Desigur, fiecare instructiune trebuie sa treaca prin toate etapele pipeline-ului dar nu e necesar ca la un moment dat pipeline-ul sa fie plin cu aceeasi instructiune. În caz ca nu exista simultan mai multe instructiuni de prelucrat (situatie practic imposibila pentru ca procesorul are permanent ceva de lucru), doar un singur stagiu al pipeline-ul va fi ocupat, ceea ce ne ofera o viteza identica cu cea observata în executia secventiala.
Pipeline-ul a fost gândit tocmai pentru a oferi posibilitatea executiei simultane a mai multor instructiuni si, în cazul ideal, performanta este multiplicata de un numar de ori dat de lungimea pipeline-ului. Astfel, daca procesorul are de executat 100 de operatii, fiecare necesitând câte patru stagii, vor fi necesare doar 100 de cicluri de tact în locul a 400, pe fiecare ciclu fiind executate câte patru operatii. Din pacate, situatia ideala nu este întâlnita niciodata pentru ca instructiunile depind unele de altele mai mult decât pare la prima vedere. Sa presupunem ca plecati de acasa cu masina personala si la jumatatea drumului va dati seama ca nu mai aveti benzina. Cum nu este nici o benzinarie prin zona si cum nimeni nu se ofera sa va tracteze, trebuie sa asteptati pe cineva sa va aduca benzina. Drept urmare, veti astepta câteva ore în trafic, incomodându-i pe ceilalti soferi, eventual va veti retrage la marginea drumului pentru a evita neplacerile pricinuite. Si cu cât drumul pe care îl aveti de parcurs este mai lung, cu atât cresc sansele sa ramâneti fara combustibil. Acelasi lucru se întâmpla si cu o instructiune daca ea nu poate fi executata decât dupa ce primeste de la alta un rezultat: ea va ramâne blocata în pipeline pâna când primeste unda verde sau va fi eliminata din pipeline, executia ei fiind amânata si lasând loc altor instructiuni care pot fi executate la acel moment. Este evident ca sansele ca acest eveniment sa aiba loc cresc odata cu cresterea numarului de stagii, tot mai multe instructiuni fiind „blocate în trafic”. Situatia descrisa duce la aparitia timpilor morti, în care procesorul nu se încalzeste si de care se poate profita, crescându-i-se frecventa.
Un procesor care îsi propune sa atinga performanta maxima la o frecventa data va realiza un compromis între avantaje si dezavantaje, fiind dotat cu un numar relativ redus de stagii. Daca scopul este atingerea de frecvente mari, netinându-se seama de performanta, atunci se va realiza un procesor cu un numar imens de stagii al pipeline-ului, procesor care sa „zaca” nefolosit o buna parte din timp, ceea ce va duce la scaderea drastica a vitezei raportata la frecventa. Exact acest lucru a realizat Intel, care a crescut numarul de stagii odata cu aparitia primului Pentium 4 (Willamette): 20 fata de 10 la Pentium III. Rezultatul a fost evident: cu toate îmbunatatirile aduse de noua arhitectura (PSB 400 fata de 133, SSE2 si altele), un Pentium 4 la 1.5 GHz era depasit deseori de un Pentium III la 1 GHz, semn ca dezavantajul datorat pipeline-ului lung nu este compensat de frecventa ridicata. O situatie similara o întâlnim si la Prescott, al carui numar de pipeline-uri a ajuns la 31 de stagii. Totodata, avem si avantaje: un cache dublu, instructiuni SSE3, etc, elemente concepute sa afecteze pozitiv viteza, dar pe alte cai. Totul pentru a se putea atinge frecvente mari, de ordinul a 4-5 GHz, frecvente irezistibile pentru orice cumparator neavizat.
Un procesor clasic executa fiecare instructiune în ordinea fireasca, asteptând terminarea fiecareia pâna sa treaca la executia celei urmatoare. Un procesor „inteligent” se bazeaza pe faptul ca timpii morti pot fi folositi pentru executia urmatoarei instructiuni. Ce se întâmpla atunci când instructiunea curenta depinde de cea precedenta, fiind necesara obtinerea rezultatului de pe urma executiei acesteia? Un caz clasic este acela al unui bloc if-then-else din cadrul oricarui limbaj de programare. Pentru executia unei anumite ramuri trebuie executata instructiunea if, dupa care se ia o decizie: se merge pe ramura A sau B. Exemplu:
if x=y then {ramura A}
else {ramura B}
Cu ajutorul unitatii de predictie (branch predictor), procesorul va executa, bazându-se pe „experientele” precedente, ramura care are sansele cele mai mari sa fie adevarata, fara a evalua conditia x=y. Cu cât algoritmul predictiei este mai bun, cu atât acuratetea ei este mai mare iar cazurile în care este aleasa ramura gresita sunt mai rare. (Nu trebuie înteles faptul ca, la alegerea ramurii gresite, rezultatul furnizat va fi incorect; situatia doar va genera timpi suplimentari.) Pentru Prescott, Intel a îmbunatatit predictia, motivul fiind faptul ca un pipeline mai lung avea nevoie stringenta de acest lucru. Modificarile sunt minore dar importante si de natura calitativa, nu cantitativa. Si anume, nu a fost marit Branch Target Buffer-ul (spatiul de memorie din procesor destinat depozitarii actiunilor precedente, pe baza carora algoritmul sa prevada actiunile viitoare) ci algoritmul a fost optimizat.
O alta unitate a procesorului este scheduler-ul. Acesta, ca si branch predictor-ul, este conceput pentru a creste eficienta CPU-ului, pentru a-l determina sa lucreze la potentialul maxim de care dispune. De data aceasta nu este vorba de ramuri cu instructiuni ce vor fi probabil executate ci de unele care vor intra sigur în executie. Procesoarele moderne detin mai multe unitati independente care îndeplinesc aceeasi sarcina (spre exemplu, toate modelele de Pentium 4 detin trei unitati de calcul cu numere întregi – ALU), însa fara acest scheduler (to schedule = a programa, cu sensul de a stabili ceva la un anumit moment), nu ar fi activa decât o singura unitate la un moment dat. Sa presupunem ca avem de efectuat trei adunari, toate urmând a fi executate de câte o unitate ALU. Dar ce ne facem când instructiunile depind una de alta, precum se poate vedea în exemplul urmator:
1. a = 1 + 2
2. b = a + 4
3. c = b – a
Este clar ca numai dupa executia primei instructiuni va putea fi executata cea de-a doua si numai dupa executia primelor doua va putea fi executata cea de-a treia. Ceea ce înseamna ca o singura unitate ALU din cele trei va fi folosita, procesorul rulând la o treime din potential. Aici intervine scheduler-ul, care programeaza executia altor instructiuni, nelegate de cele de mai sus, dând astfel câte o sarcina fiecarei unitati ALU. Prescott a necesitat modificari si în aceasta privinta, pentru a compensa cresterea numarului de stagii al pipeline-ului. Cum arhitectura curenta nu permite o modificare puternica a acestei unitati, schimbarile au fost minore.
Cum sta cu matematica?
Numarul de unitati a ramas acelasi ca la precedentele modele de P4. Segmentul ALU (Arithmetic and Logic Unit), cel care se ocupa cu calcule legate de numere întregi, a ramas divizat în trei segmente care pot prelucra datele si instructiunile independent, conform celor descrise în paragraful anterior. Doua dintre ele lucreaza la o viteza dubla fata de restul unitatilor (sunt double pumped), de aceea operatiile se executa foarte rapid. Odata cu Prescott, Intel a încercat sa elibereze al treilea ALU (cel lent) de sarcinile pe care oricum le îndeplinea cu greutate, oferind unitatilor ALU double pumped mai multe sarcini. Astfel, operatiile de tip shift si rotate erau executate de ALU-ul lent, acum ele au fost preluate de celelalte doua mai rapide.
Un exemplu practic de îmbunatatire este acela în care sunt aplicate unui numar binar operatii de multiplicare cu 2 (10 binar), caz tipic de shift în care este suficienta deplasarea cu câte un pas a fiecarui bit. De asemenea, înmultirile sunt acum realizate de unitatea FPU (Floating Point Unit), care chiar daca teoretic este mai lenta decât ALU-ul, este specializata în astfel de operatii si poate furniza rezultatele mai rapid.
Dar cu tensiunile?
Se stie ca prin cresterea „finetii” tehnologiei se pot obtine, pe de o parte temperaturi de rulare mai scazute si, pe de alta parte, frecvente mai mari de functionare. Sa ne amintim de P4 Willamette (0.18 microni) care se oprea fara drept de apel la 2 GHz pe când Northwood (0.13 microni) a atins 3.4 GHz. Mai mult, necesarul de tensiune de functionare scade, de la 1.75V pentru Willamette s-a ajuns la 1.5V pentru Northwood, iar Prescott coboara pâna la 1.287V. Pe de alta parte, arhitectura interna influenteaza puternic factorii putere disipata si temperatura de functionare, deci ar fi gresit sa afirmam ca, indiferent de alte considerente, un CPU construit pe baza unei tehnologii mai „fine” si rulând la un voltaj mai mic va fi mai rece. Ca sa nu o mai lungim, Prescott este un procesor mai fierbinte decât se dorea a fi, care consuma mult. La 3.4 GHz, un Northwood disipa 89W fata de 103W în cazul lui Prescott. Chiar daca acesta din urma este special conceput pentru frecvente mari, este nevoie de masuri speciale de precautie: în primul rând, datorita consumului excesiv, placile de baza trebuie sa suporte acest consum, în al doilea rând sistemul de racire trebuie sa fie foarte bine pus la punct.
În fine, Prescott este compatibil cu standardul VRM 10.0 (VRM = Voltage Regulator Module), ceea ce îi confera câteva avantaje, printre care posibilitatea selectarii tensiunii în pasi mai mici (0.0125V fata de 0.025V la predecesori) si Dynamic VID, adica posibilitatea ca procesorul sa-si schimbe tensiunea „on the fly”, nu doar din BIOS, cu utilitate evidenta în cazul sistemelor mobile. Dezavantajul: toate placile de baza trebuie sa suporte acest standard, deci placile vechi nu au nici o sansa sa lucreze cu Prescott.