Acest curs deschide „cutia neagră” din interiorul unui sistem embedded: ce este un set de instrucțiuni (ISA), cum au evoluat modelele de adresare de la mașini cu trei adrese până la mașini bazate pe stivă, ce separă o arhitectură CISC de una RISC - și, poate cel mai util practic, cum se calculează și se interpretează performanța reală a unui procesor, dincolo de cifra frecvenței de pe cutie.
1Obiectul și structura cursului6 min
În cursul trecut am tratat sistemele embedded „din exterior" - ce sunt, unde apar, ce le diferențiază de un calculator obișnuit. Acest curs coboară un nivel: ce se întâmplă, concret, în interiorul unității de procesare atunci când execută o instrucțiune - și de ce alegerea arhitecturii contează atât de mult pentru un sistem cu resurse limitate.
- Un sistem embedded este optimizat pentru o funcție dedicată, nu pentru flexibilitate
- Proiectarea lui înseamnă un compromis între performanță, cost, consum și fiabilitate
- Majoritatea microcontrolerelor din sistemele embedded folosesc arhitecturi RISC (ARM Cortex-M, RISC-V, AVR) - o afirmație pe care astăzi o vom putea, în sfârșit, explica tehnic
Rezultate ale învățării
- Să explicați ce este un ISA și de ce separă software-ul de implementarea hardware
- Să recunoașteți și să comparați cele patru modele de adresare a instrucțiunilor
- Să explicați diferența fundamentală dintre arhitecturile CISC și RISC
- Să scrieți și să aplicați ecuația fundamentală a performanței unui procesor
- Să calculați CPI, IPC și timpul de execuție pentru un program dat
- Să explicați de ce frecvența de ceas, luată izolat, nu spune nimic despre performanța reală
2Instruction Set Architecture12 min
Ideea esențială: ISA descrie ce poate face procesorul, nu cum o face intern. Compilatorul și programatorul de cod asamblare lucrează exclusiv la nivelul ISA, fără să aibă nevoie să știe cum arată circuitele care execută fiecare instrucțiune.
Procesoarele Intel Core și AMD Ryzen implementează ambele arhitectura x86-64, dar cu microarhitecturi interne complet diferite (pipeline, cache, predicție a ramificațiilor). Ambele execută exact același cod compilat pentru x86-64 - aceasta este puterea separării dintre ISA și implementare.
Pentru sistemele embedded, alegerea ISA influențează direct performanța, consumul energetic, dimensiunea codului executabil și disponibilitatea uneltelor software. Majoritatea microcontrolerelor moderne folosesc arhitecturi RISC (ARM Cortex-M, RISC-V, AVR), datorită eficienței energetice și simplității setului de instrucțiuni - un fir pe care îl vom relua în secțiunile despre CISC și RISC, mai jos.
3Mașini cu trei adrese10 min
Cel mai intuitiv format de instrucțiune specifică explicit ambii operanzi sursă și locația în care va fi memorat rezultatul - modelul cu trei adrese, folosit frecvent ca reprezentare intermediară de compilatoare, tocmai pentru că reflectă direct expresiile matematice din limbajele de nivel înalt.
ADD DEST, OP1, OP2 → DEST = OP1 + OP2Considerăm expresia A = B + C × D − E + F + A. Cu o mașină cu trei adrese:
MUL T, C, D ADD T, T, B SUB T, T, E ADD T, T, F ADD A, T, A
Fiecare instrucțiune este ușor de urmărit - se vede direct ce se adună cu ce, și unde ajunge rezultatul. Prețul plătit: fiecare instrucțiune trebuie să codifice trei adrese, deci instrucțiunile sunt mai lungi, iar codul executabil ocupă mai multă memorie - o problemă reală pentru un sistem embedded cu Flash limitat.
4Mașini cu două adrese8 min
Modelul cu două adrese reduce câmpurile explicite: unul dintre operanzi este folosit simultan ca sursă și ca destinație a rezultatului.
ADD OP1, OP2 → OP1 = OP1 + OP2LOAD T, C MUL T, D ADD T, B SUB T, E ADD T, F ADD A, T
Instrucțiunile sunt mai scurte decât la modelul cu trei adrese, dar codul e ușor mai greu de urmărit, pentru că valoarea inițială a primului operand este suprascrisă.
Instrucțiunea ADD EAX, EBX adună valoarea din EBX la EAX, iar rezultatul rămâne
în EAX - registrul EAX este simultan sursă și destinație. Recunoașteți acum de ce sintaxa x86
arată așa cum arată.
5Mașini cu o adresă8 min
Modelul cu o adresă merge un pas mai departe: introduce un registru special, numit acumulator (AC), folosit implicit de aproape toate operațiile aritmetice și logice. Instrucțiunea specifică explicit un singur operand; celălalt operand și destinația rezultatului sunt mereu acumulatorul.
ADD OP → AC = AC + OPLOAD C MUL D ADD B SUB E ADD F ADD A STORE A
Instrucțiunile sunt și mai scurte, iar decodificarea hardware e mai simplă - dar prețul e un număr mai mare de accesări ale memoriei (fiecare LOAD/STORE mută date către și dinspre acumulator) și o flexibilitate redusă pentru calcule complexe.
Primele generații de microprocesoare - Intel 8080, MOS Technology 6502 - foloseau extensiv registre de tip acumulator. Arhitecturile moderne folosesc în principal registre generale, dar conceptul rămâne util pentru a înțelege de ce arhitecturile au evoluat cum au evoluat.
6Mașini cu zero adrese și comparația modelelor12 min
Modelul cel mai compact: zero adrese, bazat pe o structură de date de tip stivă (LIFO - Last In, First Out). Instrucțiunile aritmetice nu mai conțin niciun operand explicit - folosesc automat primele două elemente din vârful stivei.
ADD → TOS = TOS₋₁ + TOS (TOS = Top Of Stack)PUSH B PUSH C PUSH D MUL ADD PUSH E SUB PUSH F ADD PUSH A ADD POP A
JVM (Java Virtual Machine) folosește exact acest model: instrucțiuni bytecode precum
iadd, imul, isub operează implicit pe vârful stivei de
execuție. Alegerea contribuie direct la portabilitatea aplicațiilor Java.
Comparând toate cele patru modele
| Caracteristică | 3 adrese | 2 adrese | 1 adresă | 0 adrese |
|---|---|---|---|---|
| Operanzi expliciți | 3 | 2 | 1 | 0 |
| Registru implicit | nu | nu | acumulator | stivă |
| Lungime instrucțiune | mare | medie | mică | foarte mică |
| Complexitate hardware | ridicată | medie | redusă | redusă |
| Ușurința programării | foarte bună | bună | medie | redusă |
7Arhitectura CISC10 min
Arhitecturile CISC (Complex Instruction Set Computer) au apărut într-o perioadă în care memoria era scumpă, iar compilatoarele aveau posibilități limitate de optimizare. Obiectivul: reduce numărul de instrucțiuni necesare unui algoritm, introducând instrucțiuni complexe, capabile să execute mai multe operații „dintr-o mișcare".
Procesoarele CISC includ, de regulă, sute de instrucțiuni, numeroase moduri de adresare și instrucțiuni de lungime variabilă - unele pot accesa simultan memoria, face o operație aritmetică și actualiza registre. Rezultatul: programe mai compacte, dar un procesor mult mai complex de implementat.
Intern, un procesor CISC descompune fiecare instrucțiune complexă în micro-operații mai simple, printr-un mecanism numit microcod. Programatorul „vede" o instrucțiune complexă; hardware-ul, în spate, execută o secvență de pași elementari - exact modul în care se pot adăuga instrucțiuni noi fără să se schimbe circuitele de bază ale procesorului.
Familia Intel x86 este cel mai cunoscut exemplu de arhitectură CISC. Interesant: chiar și procesoarele x86 moderne traduc intern instrucțiunile complexe în micro-operații asemănătoare celor din arhitecturile RISC - o convergență pe care o discutăm mai jos.
8Arhitectura RISC10 min
Conceptul RISC (Reduced Instruction Set Computer) a apărut din cercetări de la Berkeley și Stanford, în anii 1980, care au arătat că majoritatea programelor folosesc, de fapt, doar o fracțiune din instrucțiunile disponibile într-o arhitectură CISC. Concluzia: simplificați setul de instrucțiuni și optimizați execuția celor rămase.
Procesoarele RISC folosesc instrucțiuni de lungime fixă, un număr mare de registre generale și o arhitectură load/store: operațiile aritmetice se fac exclusiv pe registre, iar memoria este accesată numai prin instrucțiuni dedicate de încărcare și stocare.
Fluxul tipic de execuție într-un pipeline RISC clasic are cinci etape: Fetch (preluarea instrucțiunii), Decode (decodificare și citirea registrelor), Execute (operația în ALU), Memory Access (acces la memorie, dacă e nevoie) și Write Back (scrierea rezultatului în registru) - etape care se pot suprapune, instrucțiuni diferite fiind, în fiecare moment, în etape diferite ale pipeline-ului.
9RISC vs. CISC: comparație și convergență8 min
Deși multă vreme privite ca abordări concurente, implementările moderne împrumută elemente din ambele lumi: procesoarele x86 au o ISA CISC, dar execută intern micro-operații RISC-like; procesoarele ARM moderne includ predicție de ramificații și execuție speculativă - tehnici asociate istoric cu procesoarele de performanță înaltă, indiferent de familie.
| Caracteristică | RISC | CISC |
|---|---|---|
| Complexitatea instrucțiunilor | redusă | ridicată |
| Lungimea instrucțiunilor | fixă | variabilă |
| Număr registre | mare | redus/mediu |
| Pipeline | foarte eficient | mai dificil |
| Acces la memorie | load/store | direct în instrucțiuni |
| Dimensiunea codului | mai mare | mai redusă |
| Exemple | ARM, AVR, RISC-V | Intel x86, AMD64 |
Comparația trebuie privită prin prisma compromisurilor inginerești, nu ca un verdict „mai bun / mai rău" - de aceea servere și desktop-uri (unde compatibilitatea software contează enorm) continuă să folosească x86, în timp ce sistemele embedded (unde consumul și costul dominează) au migrat aproape universal spre RISC.
10Performanța unui procesor: CPI, IPC, timp de execuție7 min
Performanța unui sistem embedded nu se reduce la „cât de rapid" execută instrucțiuni - un controler de frânare are nevoie de determinism, nu de viteză maximă. Totuși, pentru a discuta riguros despre performanță, avem nevoie de o formulă precisă, nu de intuiții.
Execution Time = Instruction Count × CPI × Clock Cycleunde Instruction Count (IC) = numărul total de instrucțiuni executate, CPI (Cycles Per Instruction) = numărul mediu de cicluri per instrucțiune, iar Clock Cycle = 1 / frecvența de ceas.
Observația centrală: timpul de execuție poate fi redus pe trei căi independente - mai puține instrucțiuni (algoritm/compilator mai bun), CPI mai mic (arhitectură mai eficientă) sau frecvență mai mare (cu cost energetic și termic). Niciuna dintre ele, luată separat, nu spune toată povestea.
11CPI, IPC și ecuația de performanță9 min
CPI = Clock Cycles / Instruction CountCu cât mai mic, cu atât mai eficientă arhitectura. Instrucțiunile nu costă la fel: o adunare simplă poate lua 1 ciclu, un acces la memorie sau un salt condiționat, mai multe.
IPC = Instruction Count / Clock Cycles = 1 / CPIUn procesor scalar clasic are IPC ≤ 1. Procesoarele superscalare moderne, cu unități de execuție multiple, pot finaliza mai multe instrucțiuni pe ciclu - IPC > 1.
Două procesoare execută același program de 1 000 000 de instrucțiuni. Procesorul A rulează la 1 GHz cu CPI = 2. Procesorul B rulează la 800 MHz cu CPI = 1. Care e mai rapid?
Vezi rezolvarea
T_A = (1 000 000 × 2) / 10⁹ = 2 ms
T_B = (1 000 000 × 1) / (800 × 10⁶) = 1,25 ms
Deși procesorul B are frecvența mai mică, este mai rapid - CPI-ul redus compensează din plin diferența de frecvență. Concluzia practică: frecvența de ceas, izolată, nu e un indicator suficient al performanței reale.
În practică, performanța reală depinde de trei categorii de factori care acționează simultan: arhitectura procesorului (frecvență, pipeline, cache, număr de nuclee), eficiența codului executat (algoritm, structura datelor, localitatea de acces) și compilatorul și optimizările (alocarea registrelor, eliminarea codului redundant, selecția instrucțiunilor). Niciuna singură nu garantează performanță - toate trei trebuie aliniate.
12Erori frecvente5 min
- „Frecvența mai mare înseamnă întotdeauna un procesor mai rapid." Fals - vezi exercițiul rezolvat de mai sus. CPI-ul contează la fel de mult, uneori mai mult, decât frecvența. Comparați întotdeauna timpul de execuție real, nu doar frecvența afișată pe foaia de catalog.
- „RISC înseamnă mai puține instrucțiuni în program." de regulă e invers: un program RISC are nevoie de mai multe instrucțiuni (fiecare mai simplă) decât echivalentul CISC, dar fiecare execută în mai puține cicluri, iar suma poate fi, totuși, mai rapidă. Separați „numărul de instrucțiuni" de „timpul total de execuție" - ecuația performanței le leagă pe amândouă, nu sunt totuna.
- „CISC și RISC sunt categorii complet separate azi." Nu mai sunt curat separate - x86 (CISC ca ISA) traduce intern în micro-operații RISC-like, iar ARM (RISC) a adăugat mecanisme de performanță avansate, istoric asociate cu CISC. Tratați RISC/CISC ca pe un spectru de filozofii de proiectare, nu ca pe o etichetă binară fixă.
13Rezumat și glosar5 min
ISA este contractul stabil dintre software și hardware - ceea ce permite evoluția liberă a
implementării interne fără să strice compatibilitatea programelor existente. Modelele de
adresare (trei, două, o adresă, zero adrese) reprezintă puncte diferite pe axa
flexibilitate-vs-compactitate. RISC și CISC sunt filozofii de proiectare care astăzi converg
parțial. Iar performanța unui procesor se măsoară riguros prin ecuația Execution Time =
IC × CPI × Clock Cycle - nu prin frecvența singură.
14Întrebări de verificare8 min
- Ce reprezintă ISA și care este rolul lui în relația dintre hardware și software?
- Care sunt avantajele și dezavantajele unei mașini cu trei adrese, respectiv cu o adresă?
- Cum funcționează o mașină bazată pe stivă (zero adrese)? Dați un exemplu real.
- Care sunt principalele caracteristici ale arhitecturilor CISC și, respectiv, RISC?
- De ce arhitecturile RISC sunt preferate în sistemele embedded?
- Definiți CPI și IPC și precizați relația dintre ele.
- Scrieți ecuația performanței procesorului și explicați fiecare termen.
- De ce frecvența de ceas, luată izolat, nu este suficientă pentru evaluarea performanței?
- Calculați timpul de execuție pentru un program cu 2 000 000 de instrucțiuni, CPI = 2, la 500 MHz.
15Direcții de aprofundare2 min
Cursul următor continuă direct: acum că știm cum arată o instrucțiune și cum se măsoară performanța unui procesor, trecem la ierarhia de memorie și la particularitățile arhitecturilor ARM - cele mai folosite azi în microcontrolerele și SoC-urile pentru sisteme embedded.
Conceptul de frecvență vs. performanță discutat aici revine, aplicat concret, în Laboratorul 01 (cursurile 4-6), unde măsurați pe un Raspberry Pi 5 real cum se schimbă timpul de execuție și consumul atunci când variați frecvența procesorului.