Procesorul
Avem acum la dispoziție toate ingredientele esențiale: porți logice care calculează, registre care țin minte și un ceas care le sincronizează bătăile. Punându-le la un loc, dăm naștere unei mașini uluitoare: un procesor care nu este ferecat într-o singură menire fixă, ci execută docil, pas cu pas, orice listă de instrucțiuni codificate sub formă de numere.
Termeni: cale de date selector unitate aritmetică și logică instrucțiune cod al operației contor de program aducere · decodificare · execuție frecvență
Calea datelor
Până în acest punct am făurit piese izolate: porți logice, un sumator capabil de adunări și scăderi, precum și registre care păstrează octeți. Acum a venit momentul să le conectăm într-un mecanism viu. Între două bătăi succesive ale ceasului, în interiorul cipului se derulează o coregrafie neîntreruptă: valorile ies din registrele-sursă, călătoresc pe magistrale de cupru, străbat porțile de calcul ale sumatorului și ajung, transformate, la porțile registrelor-destinație. Acolo se așază cuminți și așteaptă. La următorul front de ceas, noul rezultat este absorbit înăuntru, iar ciclul reîncepe. Această autostradă internă pe care circulă semnalele electrice se numește cale de date (datapath).
De aici decurge o regulă de fier a fizicii, care leagă spațiul de timp: ceasul procesorului nu poate bate mai repede decât durata necesară semnalului pentru a străbate cel mai anevoios și mai lung traseu din circuit. Dacă transportul binar are nevoie de o fracțiune de nanosecundă pentru a se propaga prin toate cele opt coloane ale sumatorului, ceasul trebuie să lase timp suficient ca apele să se liniștească. Dacă am grăbi ritmul peste măsură, registrele ar captura rezultate incomplete — o adunătură de biți încă neterminați.
Unitatea aritmetică
Sumatorul pe care l-am studiat nu trăiește izolat. Alături de el se află așezate circuitele celorlalte operații de bază: modulul de scădere, precum și porțile logice care fac operații bit cu bit (ȘI, SAU, inversare). La ieșirea lor comună stă un fel de macaz feroviar numit selector (sau multiplexor): un circuit care primește rezultatele tuturor operațiilor deodată, dar lasă să treacă mai departe doar rezultatul cerut de semnalul de comandă. Întregul ansamblu poartă numele de unitate aritmetică și logică (ALU — Arithmetic Logic Unit).
Observați o strategie fascinantă a lumii digitale: când sosesc două numere, ALU calculează simultan toate operațiile posibile — adunarea, scăderea, conjuncția logică —, iar selectorul pur și simplu alege rezultatul dorit și le aruncă pe celelalte la coș! Această aparență de risipă este perfect deliberată: în electronică, tranzistoarele sunt ieftine și minuscule, dar timpul este extrem de prețios. A aștepta să pornești doar circuitul necesar ar dura mai mult decât a le lăsa pe toate să calculeze în paralel. În hardware, este adesea mult mai rapid să calculezi totul și să alegi după.
Instrucțiunea este un număr
Cum știe mașina ce anume are de făcut la fiecare pas? Ordinul trebuie să fie exprimat tot în singura limbă pe care o înțeleg circuitele: șirurile de biți. O instrucțiune nu este o vrajă abstractă, ci un simplu număr binar împărțit în căsuțe prestabilite. Fiecare grup de biți acționează ca o cheie mecanică: câțiva biți orientează macazurile selectorului spre operația dorită, iar ceilalți biți selectează registrele care trimit sau primesc datele.
În micul nostru calculator demonstrativ de mai jos, fiecare instrucțiune are lungimea de un octet (8 biți), împărțit în trei câmpuri logice. Primii trei biți reprezintă codul operației (opcode): cu trei biți putem alege una din opt comenzi posibile (pune o valoare, adună, scade, sari etc.). Următorii doi biți desemnează registrul de destinație. Ultimii trei biți alcătuiesc operandul: o valoare numerică directă, o adresă de memorie sau codul unui al doilea registru.
Când o operație lucrează cu două registre, din cei trei biți ai operandului sunt suficienți doar ultimii doi (fiindcă avem doar patru registre de deosebit). Bitul rămas liber este pur și simplu ignorat de decodificator. Asemenea mici compromisuri și spații nefolosite se regăsesc în toate procesoarele reale din istorie.
Ciclul de execuție
Pentru a parcurge un program fără să se rătăcească, mașina are nevoie de un indicator de pagină: un registru special numit contor de program (PC — Program Counter). El păstrează în permanență adresa de memorie a instrucțiunii care urmează să fie executată.
Odată pornit, procesorul repetă neobosit o buclă în trei timpi, numită ciclul de instrucțiune. Primul pas este aducerea (Fetch): contorul de program arată o căsuță de memorie, iar octetul aflat acolo este citit și adus în procesor. Al doilea pas este decodificarea (Decode): octetul este desfăcut în câmpurile sale, iar codul operației trimite impulsuri electrice spre selectoarele căii de date, pregătind circuitele potrivite. Al treilea pas este execuția (Execute): valorile trec prin unitatea aritmetică, rezultatul este salvat în registrul țintă, iar contorul de program avansează cu 1 către instrucțiunea următoare (sau face un salt la o cu totul altă adresă, dacă instrucțiunea a cerut acest lucru).
Acest mecanism de salt condiționat este scânteia magică a calculatoarelor. Fără el, un procesor ar fi doar o cutie muzicală rigidă, care derulează o listă fixă de comenzi de la cap la coadă o singură dată. Datorită saltului condiționat („dacă ultimul rezultat nu este zero, sari înapoi la pasul 2”), mașina poate lua decizii, poate relua bucle de calcul și poate reacționa flexibil la datele pe care le prelucrează. Din îmbinarea aritmeticii cu saltul se naște ceea ce numim, pe bună dreptate, comportament autonom.
Mașina, la lucru
Priviți panoul de mai jos: aici avem întregul calculator asamblat și gata de drum — memoria cu programul, contorul de adrese, decodificatorul, registrele interne și calea de date. Programul preîncărcat are o sarcină limpede: adună numerele de la 1 la 5. Fiecare apăsare pe „Un tact” parcurge o fază a ciclului (aducere, decodificare sau execuție), așa încât o instrucțiune completă se împlinește la fiecare trei tacte.
programul
registrele
ce a arătat
Încercați și al doilea program din meniu: el realizează înmulțirea numerelor 3 și 4. Mașina noastră nu are o poartă specială de înmulțire; în schimb, programul adună numărul 3 de patru ori la rând, scăzând câte 1 dintr-un registru-contor până ajunge la zero. Iată lecția centrală a informaticii: orice operație complexă care lipsește din hardware poate fi construită prin compunerea inteligentă a câtorva instrucțiuni elementare.
Frecvența
Viteza cu care bate inima procesorului se numește frecvență de ceas și se măsoară în herți. O frecvență de trei gigaherți (3 GHz) înseamnă că ceasul ticăie de trei miliarde de ori pe secundă! La această scară amețitoare, un tact durează doar o treime de nanosecundă — răstimpul infim în care lumina abia apucă să înainteze zece centimetri prin spațiu.
Așa cum am văzut, o instrucțiune are nevoie de mai multe tacte pentru a se finaliza. Cum reușesc atunci calculatoarele de astăzi să fie atât de rapide? Printr-o tehnică numită bandă de asamblare (pipelining), asemănătoare unei spălătorii automate: în timp ce o haină se usucă în uscător (faza de execuție), următoarea este spălată în mașină (decodificarea), iar o a treia este sortată în coș (aducerea). Fiecare haină stă trei ore în total, dar la fiecare oră iese o haină curată! Lucrând la mai multe comenzi aflate în faze diferite, procesoarele moderne finalizează în medie aproape o instrucțiune la fiecare bătaie de ceas.
Să facem un ultim pas înapoi și să privim cu atenție: programul pe care l-a executat mașina noastră stătea scris în memorie sub formă de octeți obișnuiți, exact ca numerele adunate. Nimic din structura fizică a memoriei nu deosebește o instrucțiune de o dată numerică oarecare. Ce anume transformă un număr inert într-o comandă vie este doar faptul că spre el a arătat contorul de program. Această realizare epocală — contopirea programului cu datele în aceeași memorie — deschide o lume cu totul nouă, pe care o vom explora în lecția următoare.