Tots pensem en la CPU com el "cervell" d'un ordinador, però què significa això en realitat? Què passa amb milers de milions de transistors perquè funcioni el vostre equip? En aquesta nova minisèrie de quatre parts, ens centrarem en el disseny de maquinari de l’ordinador que inclou les entrades i sortides del que funciona un ordinador.

Aquesta sèrie tractarà l'arquitectura d'ordinadors, el disseny de circuits de processador, VLSI (integració a gran escala), la fabricació de xips i les tendències futures en informàtica. Si sempre us han interessat els detalls sobre com funcionen els processadors a l'interior, comenceu perquè és el que voleu saber per començar.

Començarem a un nivell molt alt amb el que fa un processador i com encaixen els blocs de construcció en un disseny funcional. Això inclou nuclis de processador, jerarquia de memòria, predicció de sucursals i molt més. En primer lloc, necessitem una definició bàsica del que fa la CPU. L'explicació més senzilla és que una CPU segueix un conjunt d'instruccions per operar en un conjunt d'entrades. Per exemple, això pot ser llegir un valor de la memòria, afegir-lo a un altre valor i, finalment, emmagatzemar el resultat en una ubicació diferent. També pot ser alguna cosa més complex, com dividir dos nombres, si el resultat del càlcul anterior és superior a zero.

Quan voleu executar un programa com ara un sistema operatiu o un joc, el programa és un conjunt d’instruccions que la CPU ha d’executar. Aquestes instruccions es carreguen de la memòria a un processador senzill i s’executen una a una fins que s’acaba el programa. Tot i que els desenvolupadors de programari escriuen els seus programes en llenguatges d’alt nivell com C ++ o Python, el processador no ho pot entendre. Només entén l’1 i el 0, de manera que necessitem una manera de representar el codi en aquest format.




Els programes es compilen en una sèrie d’instruccions de baix nivell. llenguatge assemblador Com a part de l'Arquitectura del conjunt d'instruccions (ISA). Aquest és el conjunt d’instruccions que la CPU està creada per entendre i executar. Alguns dels ISA més habituals són x86, MIPS, ARM, RISC-V i PowerPC. De la mateixa manera que la sintaxi per escriure una funció en C ++ és diferent d'una funció que fa el mateix a Python, cada ISA té una sintaxi diferent.




Aquests ISA es poden dividir en dues categories principals: longitud fixa i longitud variable. RISC-V ISA utilitza instruccions de longitud fixa, el que significa que determina quin tipus d’ordre és un nombre determinat de bits predefinits en cada ordre. Això és diferent de x86 mitjançant instruccions de longitud variable. A x86, les instruccions es poden codificar de diferents maneres i amb diferents nombres de bits per a diferents parts. A causa d'aquesta complexitat, el descodificador d'ordres de les CPU x86 sol ser la part més complexa de tot el disseny.

Les instruccions de longitud fixa permeten una descodificació més fàcil a causa de la seva naturalesa normal, però limiten el nombre total d’instruccions que pot suportar un ISA. Les versions habituals de l'arquitectura RISC-V tenen aproximadament 100 directives i, tot i que és de codi obert, és propietari de x86 i ningú sap quantes directives hi ha. La gent sol creure que hi ha diversos milers d’instruccions x86, però el nombre exacte no està disponible públicament. Tot i les diferències entre els ISA, tots tenen essencialment la mateixa funcionalitat bàsica.







Ara estem preparats per engegar el nostre ordinador i posar en marxa alguna cosa. L’execució d’una ordre té en realitat algunes parts bàsiques que es desglossen en moltes etapes d’un processador.




El primer pas és portar la instrucció de la memòria a la CPU per començar a executar-la. En el segon pas, l'ordre es descodifica perquè la CPU pugui entendre de quin tipus d'instrucció es tracta. Hi ha molts tipus, com ara ordres aritmètiques, instruccions de derivació i instruccions de memòria. Un cop la CPU aprèn quin tipus d’instrucció està executant, els operands de la instrucció es recullen de la memòria o dels registres interns de la CPU. Si voleu afegir el número A al número B, no podeu afegir sense conèixer realment els valors A i B. La majoria dels processadors moderns són de 64 bits, el que significa que la mida de cada valor de dades és de 64 bits.




Després que la CPU tingui els operands per a la instrucció, passa a l'etapa d'execució on es fa el processament a l'entrada. Això podria ser afegir números, fer una manipulació lògica dels números o simplement passar els números sense canvis. Un cop calculat el resultat, és possible que calgui accedir a la memòria per emmagatzemar el resultat, o bé la CPU pot mantenir el valor en un dels seus registres interns. Després de guardar el resultat, la CPU actualitzarà l'estat dels diferents elements i passarà a la següent instrucció.

Aquesta explicació és, per descomptat, una simplificació important i la majoria dels processadors moderns divideixen aquestes poques etapes en 20 o menys etapes per augmentar l’eficiència. Això vol dir que, tot i que el processador iniciarà i acabarà diverses instruccions en cada cicle, qualsevol instrucció pot requerir 20 o més cicles per completar-lo de principi a fi. Sovint es fa referència a aquest patró com a canonada perquè triga un temps a omplir-la i el líquid passarà per complet, però quan s’ompli obtindreu una sortida constant.

Tot el cicle pel qual passa una instrucció és un procés coreogràfic molt estricte, però no totes les instruccions poden acabar al mateix temps. Per exemple, la inserció pot ser molt ràpida, mentre que dividir o carregar de memòria pot trigar centenars de cicles. En lloc d’aturar tot el processador quan s’acaba una instrucció lenta, la majoria dels processadors moderns queden sense funcionament. Això vol dir que determinaran quina ordre serà més útil per executar en un moment concret i emmagatzemaran altres instruccions que no estiguin preparades. Si la instrucció actual encara no està preparada, el processador pot avançar en el codi per veure si hi ha alguna cosa més a punt.

A més de l'execució inusual, els processadors moderns típics, arquitectura superescalar. Això significa que, en qualsevol moment, el processador executa moltes instruccions alhora a cada etapa de la canonada. A més, potser hi ha centenars d’altres que esperen per començar la seva execució. Per tal de poder executar moltes instruccions alhora, tindran diverses còpies de cada etapa de la canonada dins dels processadors. Si un processador veu que les dues ordres estan preparades per executar-se i, en lloc d’esperar que acabin per separat, les executa alhora si no hi ha cap dependència entre elles. Una aplicació comuna d’això s’anomena Simultaneous Multithreading (SMT), també coneguda com a Hyper-Threading. Tot i que els processadors Intel i AMD actualment admeten SMT bidireccionals, IBM ha desenvolupat xips que admeten SMT de vuit vies.

Per aconseguir aquesta execució acuradament coreografiada, un processador té molts elements addicionals a més del nucli bàsic. Hi ha centenars de mòduls separats en un processador, cadascun amb un propòsit específic, però tractarem els conceptes bàsics. Els dos més grans i més útils són els predictors de memòria cau i de branca. Les estructures addicionals que no cobrirem inclouen reordenar memòries intermèdies, taules d’àlies de registre i estacions de reserva.

El propòsit de les memòries cau pot ser confús, ja que sovint emmagatzemen dades com RAM o SSD. El que distingeix les memòries cau són les latències i velocitats d’accés. Tot i que la memòria RAM és extremadament ràpida, la CPU té un ordre de magnitud molt lent. La memòria RAM pot trigar centenars de cicles a respondre amb dades i el processador es queda sense fer res. Si les dades no es troben a la memòria RAM, poden trigar desenes de milers de cicles a accedir a les dades d’un SSD. Sense memòries caus, els nostres processadors s’aturaven.

Els processadors solen tenir tres nivells de memòria cau. jerarquia de memòria. La memòria cau L1 és la més petita i ràpida, la L2 al centre i la memòria cau L3 és la més gran i lenta. A la memòria cau de la jerarquia hi ha petits registres que emmagatzemen un valor de dades únic durant el càlcul. Aquests registres són, per ordre de mida, els dispositius d’emmagatzematge més ràpids del vostre sistema. Quan un compilador converteix el programa d'alt nivell al llenguatge de compilació, determina la millor manera d'utilitzar aquests registres.

Quan la CPU sol·licita dades de la memòria, primer comprova si aquestes dades s’emmagatzemen a la memòria cau L1. Si és així, es pot accedir ràpidament a les dades en pocs cicles. Si no està disponible, la CPU comprova L2 i, a continuació, busca la memòria cau de L3. Les memòries cau solen implementar-se de manera transparent al nucli. El nucli només demanarà algunes dades sobre una adreça de memòria concreta i respondrà a qualsevol nivell de la seva jerarquia. La mida i la latència normalment augmenten en ordres de magnitud a mesura que passem a les etapes posteriors de la jerarquia de la memòria. Finalment, si la CPU no pot trobar les dades que busca a cap de les memòries cau, només passarà a la memòria principal (RAM).

En un processador típic, cada nucli tindrà dues memòries cau L1: una per a dades i una per a instruccions. Les memòries cau de L1 tenen uns 100 kilobytes en total i la mida pot variar segons el xip i la generació. Normalment, cada arquitectura té una memòria cau L2, però algunes arquitectures es poden compartir entre dos nuclis. Les memòries cau de L2 solen tenir diversos centenars de kilobytes. Finalment, hi ha una única memòria cau L3 que ronda desenes de megabytes compartits en tots els nuclis.

Quan un processador executa codi, les instruccions i els valors de dades que utilitza més sovint es guarden a la memòria cau. Això agilitza notablement l'execució, ja que el processador no ha d'anar constantment a la memòria principal per obtenir les dades que necessita. Parlarem més sobre com s’implementen aquests sistemes de memòria a la segona i tercera part d’aquesta sèrie.

A més de les memòries cau, un dels altres blocs de construcció importants d’un processador modern és correcte predictor de branca. Les instruccions de sucursal són similars a les sentències "if" d'un processador. Si la condició és certa, s'executa un conjunt d'ordres i, si la condició és falsa, s'executa una seqüència d'ordres. Per exemple, és possible que vulgueu comparar dos nombres i, si són iguals, podeu realitzar una funció i, si és diferent, podeu realitzar una altra funció. Aquestes instruccions de sucursal són extremadament comunes i poden representar aproximadament el 20% de totes les instruccions d’un programa.

A la superfície, aquestes instruccions de derivació poden no semblar un problema, però en realitat aconseguir un processador correcte pot ser molt difícil. És molt important saber-ho, ja que en qualsevol moment la CPU pot estar executant deu o vint instruccions alhora quin instruccions per dur a terme. Pot trigar 5 bucles per determinar si l'ordre actual és una branca i 10 bucles més per determinar si la condició és certa. Durant aquest temps, és possible que el processador hagi començat a executar dotzenes d’instruccions addicionals sense saber si eren instruccions correctes.

Per solucionar aquest problema, tots els processadors moderns d'alt rendiment fan servir una tècnica anomenada especulació. Això vol dir que el processador seguirà les instruccions de la sucursal i predirà si l'adquisició de la sucursal o no. Si la suposició és correcta, el processador ha començat a executar instruccions posteriors, cosa que proporciona un guany de rendiment. Si la suposició és incorrecta, el processador atura l'execució, elimina les instruccions incorrectes que va començar a executar i comença des del punt correcte.

Aquests predictors de branques són algunes de les primeres formes d’aprenentatge de maquinistes perquè el pronòstic aprèn gradualment el comportament de les branques. Si endevina massa malament, començarà a aprendre el comportament correcte. Les dècades d’investigació sobre tècniques de predicció de branques han donat com a resultat una precisió de més del 90% en els processadors moderns.

Tot i que l’especulació ofereix enormes guanys en el rendiment, també exposa vulnerabilitats, tot i que el processador pot executar instruccions ja preparades en lloc d’esperar-ne d’ocupades. El famós atac Spectre explota els errors de predicció i especulació de branques. L'atacant utilitza codi dissenyat especialment per forçar el processador a executar especulativament codi que fuiti els valors de memòria. Alguns aspectes de l'especulació es van haver de redissenyar per garantir que no es poguessin filtrar les dades, cosa que va provocar una lleugera caiguda del rendiment.

L’arquitectura utilitzada en processadors moderns ha recorregut un llarg camí en les darreres dècades. Les innovacions i el disseny intel·ligent han donat com a resultat més rendiment i un millor ús del maquinari subjacent. Els fabricants de CPU són de màxim secret sobre les tecnologies dels seus processadors, de manera que és impossible saber exactament el que passa dins. Tot i això, els conceptes bàsics sobre el funcionament dels ordinadors s’estandarditzen en tots els processadors. Intel pot afegir la seva salsa oculta per augmentar els percentatges de visites a la memòria cau o AMD pot afegir un estimador de branca avançat, però tots dos fan la mateixa tasca.

Aquesta primera mirada i visió general va cobrir la majoria dels conceptes bàsics sobre el funcionament dels processadors. A la següent secció, parlarem de com es dissenyen els components que entren a la CPU, que cobreixen les portes lògiques, el rellotge, la gestió de l’alimentació, els diagrames de circuits i molt més. Segueix mirant-nos.

Lectures suggerides:

Crèdit masthead: Primer pla de la placa de circuit electrònic de Raimuda