L'architettura del calcolatore
Nel modulo dedicato alla logica digitale abbiamo costruito, pezzo dopo pezzo, il vocabolario elettrico con cui parlano i circuiti, dalle porte logiche che accettano segnali e restituiscono altri segnali fino al sommatore, quel piccolo circuito capace di sommare numeri binari raccogliendo i riporti come una fila di persone che si passano il peso di uno zaino. Tutto questo poteva sembrare un gioco da tavolo, e invece stavamo imparando a conoscere i mattoni con cui è costruito ogni processore del mondo, perché dentro un chip moderno convivono diversi miliardi di porte logiche, e la domanda di questo modulo è come questi interruttori minuscoli riescano a comportarsi come una macchina organizzata, capace di eseguire programmi scritti da esseri umani.
La risposta arriva da un'idea nata negli anni quaranta, quando i calcolatori erano macchine enormi piene di valvole e cavi, e da allora la pianta di quasi ogni computer costruito, dal telefono nella tua tasca ai supercalcolatori dei centri di ricerca, riconosce ancora lo stesso disegno. In questo modulo partiremo dal concetto che ha cambiato tutto, cioè il programma memorizzato, poi visiteremo a fondo i luoghi dove avviene il lavoro, la memoria che conserva, il processore che calcola, i bus che fanno da strade e infine la scheda madre che ospita tutti questi abitanti sotto lo stesso tetto, e per ogni tappa aggiungeremo uno strato di dettagli alla carta geografica che abbiamo disegnato nel modulo scorso.
Per apprezzare la rivoluzione conviene guardare da vicino il primo di questi mostri, l'ENIAC, costruito tra il 1943 e il 1946 nell'università della Pennsylvania da John Mauchly e J. Presper Eckert per conto dell'esercito americano, una macchina fatta di diciottomila valvole termoioniche, millecinquecento relè e seimila interruttori multiposizione, pesante trenta tonnellate, grande quanto un appartamento e affamata di centoquaranta chilowatt di elettricità, una potenza tale da far tremare la rete del quartiere ogni volta che veniva accesa. Le valvole sono piccole lampadine che lavorano come interruttori comandati dal segnale elettrico, e come ogni lampadina si bruciano, tanto che i tecnici trascorrevano le giornate a cercare quella guasta tra le migliaia accese, e programmare l'ENIAC significava collegare a mano una vera foresta di cavi tra le sue prese e ruotare quei seimila interruttori, un lavoro di giorni che richiedeva pazienza da chirurgo e rendeva la macchina potentissima nei calcoli e goffa nel cambiare compito.
La svolta arrivò proprio da quel difetto, e la storia la racconta con nomi e date che vale la pena fissare. Nel 1945 John von Neumann, matematico ungherese trasferitosi negli Stati Uniti e già considerato il più grande matematico vivente, scrisse un rapporto sul progetto di un successore dell'ENIAC chiamato EDVAC, e lì espresse con chiarezza l'idea che anche i programmi potessero essere scritti come numeri e conservati nella memoria della macchina, accanto ai dati che dovevano elaborare, così da poter cambiare compito alla macchina con la facilità con cui si riscrive una pagina anziché si spostano cavi. Il primo calcolatore operativo a usare davvero questo principio fu l'EDSAC, costruito nel 1949 a Cambridge sotto la guida di Maurice Wilkes, mentre von Neumann portava avanti a Princeton la macchina IAS, che aveva quattromilanovantasei celle di memoria da quaranta bit ciascuna e un registro speciale, chiamato accumulatore, in cui confluivano per abitudine i risultati dei calcoli, e il modello che ne scaturì, con istruzioni e dati che convivono nella stessa memoria, è il fondamento su cui poggia tutta l'informatica successiva.
Lo schema che trovi qui sopra mostra il modello delineato da von Neumann, con la memoria collegata all'unità centrale, formata dall'unità aritmetica e logica e dall'unità di controllo, mentre da un lato entrano i dati e dall'altro escono i risultati. Osservandolo si scorge il punto debole che porta il suo nome, il collo di bottiglia di von Neumann, perché esiste una sola strada che collega la memoria al processore e su quella strada devono viaggiare sia le istruzioni sia i dati, come una via di paese percorsa dai camion della spesa e da quelli della spazzatura, e questa strada stretta resta, ancora oggi, uno dei limiti principali alla velocità dei computer, come vedremo più avanti quando parleremo delle cache, che sono gli scaffali di emergenza inventati proprio per aggirarla.
L'idea del programma memorizzato scatenò una corsa che dura tuttora, e per orientarla gli storici dividono i calcolatori in generazioni, una comoda fila di tappe che conviene conoscere. La prima generazione, dagli anni quaranta alla metà degli anni cinquanta, è l'epoca delle valvole, con macchine come l'ENIAC costose, calde e fragili; la seconda generazione, tra il 1955 e il 1965, sostituì le valvole con il transistor, l'interruttore semiconduttore senza filamenti che abbiamo incontrato nel modulo di elettronica, e i computer diventarono più piccoli, più affidabili e molto più diffusi; la terza generazione, dal 1965 al 1980, portò i circuiti integrati, cioè interi circuiti fotografati su una fetta di silicio, e lì nacquero i primi veri minicomputer; dalla quarta generazione, iniziata intorno al 1980, la miniaturizzazione sposò l'integrazione a grandissima scala, con milioni e poi miliardi di transistor su un solo chip, e sono i suoi figli a stare oggi sulle nostre scrivanie e nelle nostre tasche. A tenere il ritmo di questa corsa ci pensò una profezia autocandidantesi, la legge di Moore, formulata nel 1965 da Gordon Moore, cofondatore di Intel, che osservò il numero di transistor sui chip raddoppiare con regolarità e previde che la crescita sarebbe continuata, tanto che oggi per legge di Moore s'intende un raddoppio circa ogni diciotto mesi, equivalente a una crescita del sessanta per cento l'anno sostenuta per decenni, un ritmo che spiega come il computer più potente di cinquant'anni fa sia oggi superato da un giocattolo da pochi euro.
Passiamo ora alla memoria, che si presenta come una lunghissima fila di celle uguali, ognuna contrassegnata da un numero progressivo chiamato indirizzo, come le case di una via individuate dal numero civico, e il processore, quando ha bisogno di un dato, bussa proprio a quel numero. Ogni cella custodisce una parola fatta di bit, cioè un pacchetto di zeri e di uno di larghezza fissa, oggi quasi sempre sessantaquattro bit, e se la memoria ha un milione di celle gli indirizzi vanno da zero fino a novecentonovantanovemilanovecentonovantanove, senza eccezioni né preferenze, e l'indirizzo stesso è a sua volta un numero binario che viaggia sui fili del bus degli indirizzi fino a raggiungere il portone giusto.
La memoria di lavoro del computer si chiama RAM, acronimo di Random Access Memory, memoria ad accesso casuale, e la fotografia qui sopra mostra i suoi moduli, listelli verdi coperti di chip neri, mentre vengono infilati negli alloggiamenti della scheda madre. La sua caratteristica principale è la volatilità, perché dentro ogni cella ci sono minuscoli condensatori che trattengono la carica elettrica soltanto finché arriva corrente, e per questo, quando spegni il computer, tutto ciò che la RAM conteneva svanisce come scritte lasciate sulla sabbia dalla marea, ed è anche per questo che quei chip vanno rinfrescati di continuo, con una ricarica elettrica ripetuta ogni pochi millisecondi, il che la rende più lenta e più densa delle memorie statiche usate altrove. Questa dimenticanza ha un suo senso, perché la RAM è il banco da lavoro del processore, la superficie su cui si appoggiano programmi e documenti mentre sono in uso, e lavorare su un piano libero e velocissimo vale più di qualsiasi conservazione perpetua, compito che spetta ai dischi, lenti ma tenaci.
Il banco da lavoro, però, non è l'unico ripiano della officina, e i progettisti hanno disposto i ripiani in una vera e propria gerarchia di memoria, dal più veloce e piccolo al più capace e lento, con numeri che danno il capogiro. In cima ci sono i registri del processore, raggiungibili in un singolo ciclo di clock, cioè in una frazione di miliardesimo di secondo; subito sotto troviamo la cache di primo livello, una manciata di decine di kilobyte saldata accanto al cuore del chip, che risponde in pochi cicli; poi la cache di secondo livello, dalle centinaia di kilobyte ai pochi megabyte, e sui processori recenti perfino una di terzo livello, che richiedono qualche decina di cicli; ancora più in basso c'è la RAM, veloce ma molto più lontana, con i suoi tempi di decine di nanosecondi, e infine i dischi, che misurano i propri tempi in millisecondi, cioè milioni di nanosecondi. Tra un accesso al registro e un accesso al disco corre un rapporto di circa un milione a uno, la distanza tra un gesto della mano e un viaggio in treno, e l'intera gerarchia esiste per un solo motivo, il principio di località, che osserva come i programmi reali tornino a toccare spesso gli stessi dati e spesso dati che abitano in celle vicine tra loro, come chi cucina riprende continuamente lo stesso mestolo e gli ingredienti appoggiati accanto.
Il principio di località rende possibile un trucco raffinato e decisivo. Quando il processore legge una cella di RAM, la cache copia in realtà tutto il vicinato, un blocco di celle attorno a quella richiesta, tenendolo pronto sul ripiano più alto, e alle letture successive il processore chiede prima alla cache, trovando quasi sempre ciò che cerca e risparmiando la lunga passeggiata fino alla RAM, e solo di rado deve scendere davvero, ed è in quel raro caso che la macchina si sente lenta, quando apri per la prima volta un programma pesante e il disco lavora per portare tutto al suo posto. I libri di testo distinguono la località temporale, che premia il riuso degli stessi dati, da quella spaziale, che premia la vicinanza, e buona parte dell'ingegneria dei processori moderni consiste nel prevedere con sempre maggiore finezza cosa il programma vorrà subito dopo, un gioco di indovini giocato a miliardi di volte al secondo.
Al centro di tutto c'è il processore, il cuore del computer, un chip pieno di porte logiche organizzate in tre squadre che collaborano senza posa. La prima squadra è fatta dei registri, piccoli contenitori velocissimi dentro cui si appoggiano i numeri su cui si sta lavorando, pensali come i taccuini che un commesso tiene sul bancone, a portata di mano e riscritti di continuo. La seconda è l'unità aritmetica e logica, la calcolatrice interna che somma, sottrae e confronta, e la terza è l'unità di controllo, il direttore d'orchestra che a ogni istante decide quale operazione eseguire, aprendo e chiudendo i passaggi elettrici tra registri e calcolatrice come un direttore che dà la parola ai violini, e il disegno complessivo di queste squadre prende il nome di microarchitettura, cioè la realizzazione interna del processore, di cui parleremo tra poco.
Il disegno qui sopra ritrae l'interno del processore durante il suo lavoro quotidiano, che consiste in un rito sempre uguale chiamato ciclo fetch-decode-execute, in italiano preleva, decodifica ed esegui. A ogni giro il processore preleva dalla memoria la prossima istruzione del programma, la porta dentro un registro apposito e la decodifica per capire di che tipo si tratti, poi la esegue usando la calcolatrice o muovendo dati, e infine ricomincia da capo con la seguente, migliaia di milioni di volte al secondo. Il ritmo di questo giro è scandito dal clock, un piccolo oscillatore che batte come un metronomo, e il numero dei battiti al secondo, che oggi si misura contando i miliardi con l'unità gigahertz, dà il tempo a tutta la macchina.
Per capire fino in fondo il rito conviene dare un nome ai suoi attori principali, quattro registri che Tanenbaum presenta come gli strumenti permanenti del mestiere. Il contatore di programma, nella sigla inglese Program Counter o PC, tiene l'indirizzo della prossima istruzione da prelevare e avanza di una parola a ogni prelievo; il registro istruzione, o Instruction Register, accoglie l'istruzione appena letta mentre viene decodificata; il registro d'indirizzo di memoria, o MAR, e il registro dei dati di memoria, o MDR, fanno da porta e da vassoio tra processore e memoria, perché il primo ospita il numero della cella da cui leggere o in cui scrivere, e il secondo ospita il valore che viaggia in quel momento. Con questi nomi in mano, guardiamo un prelievo con i numeri davvero scritti sul foglio, così il rito smette di essere un'astrazione.
Immagina che il contatore di programma contenga il numero cento e che nella cella cento della memoria viva la parola che significa somma il contenuto della cella duecentodue al registro A. Il processore copia il cento nel registro d'indirizzo, che viene posto sul bus degli indirizzi, la memoria riconosce il numero e risponde mandando la parola richiesta, che attraverso il bus dei dati entra nel registro dei dati e da lì nel registro istruzione. La decodifica rivela che servono due mosse, copiare il numero duecentodue nel registro d'indirizzo e leggere di nuovo, così il valore contenuto nella cella duecentodue arriva nel registro dei dati e viene consegnato alla calcolatrice insieme al contenuto del registro A, e il risultato trova posto nell'accumulatore o in un altro registro scelto dall'istruzione. Tutta questa danza, che abbiamo raccontato in tre frasi lente, occupa pochi cicli di clock, e poi il dito del contatore di programma punta alla cella centouno e il rito ricomincia.
C'è un ospite che interrompe questo rito senza bussare, ed è importante conoscerlo perché vive in ogni computer che premi un tasto o muovi un mouse. Se il processore dovesse chiedere a ogni dispositivo, ogni pochi istanti, se ha novità da raccontare, sprecherebbe la maggior parte della sua vita in cortesie inutili, e per questo esiste il meccanismo dell'interrupt, cioè dell'interruzione, con cui una periferica alza un segnale elettrico speciale per chiamare la CPU. Quando premi un tasto, il controllore della tastiera genera un'interruzione, il processore termina con calma l'istruzione che sta eseguendo, appunta su un taccuino interno il punto esatto in cui era arrivato, e salta a una procedura di servizio, un piccolo programma che raccoglie il codice del tasto premuto e lo deposita in memoria; finita la faccenda, il processore torna al lavoro interrotto esattamente da dove aveva lasciato, come un cuoco che, mentre impasta, si gira un istante verso il campanello del banco, serve il cliente e riprende la pasta con la mano nella stessa posizione di prima, senza aver perso il filo.
A questo punto sorge una domanda naturale, e cioè come fa il processore a capire le istruzioni che riceve, e la risposta è che ogni modello di processore possiede un vocabolario proprio chiamato set di istruzioni, in inglese instruction set, che elenca quali comandi la macchina riconosce, cosa sa calcolare e cosa le resta estraneo. È il contratto tra il software e l'hardware, perché chi scrive programmi si adegua a quel vocabolario e chi costruisce il chip lo rispetta alla lettera, e le istruzioni sono sorprendentemente semplici, copia questo numero, somma questi due, confronta e saltiamo altrove, tanto che ogni programma grande, dal videogioco al navigatore, si scompone in lunghe sequenze di piccolissimi ordini di questo tipo.
Questo vocabolario merita di essere collocato sulla mappa dei livelli che compongono un calcolatore, perché il computer è una torre di traduzioni, e ognuno abita un piano. In basso sta il livello dei circuiti digitali, fatto di porte logiche, sopra di esso sta la microarchitettura, cioè la disposizione concreta di registri, calcolatrice e direttore d'orchestra dentro il chip, e sopra ancora sta il livello del set di istruzioni, che è la facciata della macchina, il piano che i programmi vedono e al quale devono rivolgersi. La distinzione ha una conseguenza pratica affascinante, e cioè che due processori con la stessa facciata, lo stesso vocabolario, possono avere interni completamente diversi, così come due ristoranti che servono lo stesso menu possono avere cucine organizzate in modo opposto, e per questo i programmi continuano a funzionare anche quando cambi generazione di processore.
La storia dei vocabolari conosce una diatriba celebre, raccontata da Tanenbaum con dovizia di particolari, ed è lo scontro tra le filosofie CISC e RISC. Fino agli anni settanta la tendenza era quella di arricchire i vocabolari di istruzioni sempre più potenti e specializzate, una scuola chiamata CISC, in cui ogni istruzione complessa veniva spezzettata dentro il chip in sequenze di mosse più semplici; verso la fine di quegli anni David Patterson a Berkeley e John Hennessy a Stanford scelsero la strada opposta, progettando processori con un vocabolario essenziale di istruzioni semplici, ciascuna eseguita rapidamente, nella scuola chiamata RISC, e i loro figli diretti furono i processori SPARC e MIPS. Con il tempo le due scuole si sono avvicinate, perché i progettisti moderni fanno convivere vocabolari ricchi con interni essenziali, traducendo all'ingresso le istruzioni complesse in operazioni semplici, e chi compra un computer oggi eredita il meglio di entrambe le tradizioni.
Per rendere il vocabolario familiare conviene fissare quattro parole che lo popolano in ogni dove, e sono le istruzioni di caricamento, memorizzazione, somma e salto, chiamate load, store, add e jump nei documenti tecnici inglesi. La prima porta una parola dalla memoria a un registro, la seconda riporta un registro nella memoria, la terza consegna due numeri alla calcolatrice e deposita il risultato, e la quarta sposta il contatore di programma a un indirizzo scelto, facendo saltare l'esecuzione da un punto all'altro del programma, e con queste quattro mosse più qualche compagna di viaggio si scrive tutto. Una somma tra due numeri conservati in memoria diventa così una sequenza di cinque piccoli ordini, porta il primo numero dal magazzino al banco, porta il secondo, sommali, riporta il risultato in magazzino, passa all'ordine successivo, e un programma che modifica le tue foto preferite è, in fondo, una catena di milioni di ordini altrettanto umili eseguita con disciplina assoluta.
Abbiamo detto che il rito preleva, decodifica ed esegui si ripete con regolarità da orologio, e i progettisti si sono chiesti da subito se fosse possibile sovrapporre i giri, così come in una panetteria i panini avanzano su un nastro e ogni stazione fa il suo gesto, la prima taglia, la seconda farcisce, la terza chiude, e mentre il primo panino viene chiuso il secondo viene farcito e il terzo viene già tagliato, senza che nessuna mano resti ferma. Questa è l'idea della pipeline, la catena di montaggio interna del processore, in cui le fasi del rito sono divise fra postazioni specializzate che lavorano su istruzioni diverse contemporaneamente, e grazie a essa il processore completa mediamente più di un'istruzione a ogni ciclo di clock pur impiegando diversi cicli per ciascuna. La pipeline soffre però di un guastafeste, e sono i salti condizionali di cui abbiamo appena parlato, perché quando arriva un salto che dipende da un risultato ancora in lavorazione la catena deve indovinare quale panino arriva dopo, e se indovina male deve svuotare i piani di lavoro e ricominciare, ed è per arginare questi vuoti che i chip moderni dedicano ingegno e transistor alla previsione dei salti, un altro capitolo della corsa a prevedere il futuro.
Finora abbiamo parlato degli abitanti della città digitale, e ora guardiamo alle strade che li collegano, i bus, parola che in inglese significa autobus, nome azzeccato perché sullo stesso percorso condiviso viaggiano insieme dati, indirizzi e comandi, tra processore, memoria e periferiche. Un bus è un fascio di fili paralleli, ognuno dei quali trasporta un bit alla volta, e la larghezza del bus, cioè il numero dei fili, decide quanta informazione viaggia in ogni corsa, come il numero delle corsie decide quante auto attraversano un ponte nello stesso istante. I bus dei computer di oggi muovono tipicamente sessantaquattro bit per corsa, e quel numero, insieme alla frequenza del clock e al numero di corse per secondo, determina quanto scorrevole sia il traffico tra i componenti.
Guardando i bus da vicino scopriamo che ogni strada è in realtà un fascio di tre strade sovrapposte, con compiti ben distinti. La via dei dati trasporta le parole che entrano e escono, la via degli indirizzi trasporta il numero della cella o del dispositivo chiamato, e la via di controllo trasporta gli ordini di servizio, leggi ora, scrivi ora, ho finito, ed è comprensibile solo se tutti parlano la stessa lingua, che prende il nome di protocollo del bus, un regolamento scritto che fissa anche le forme dei connettori e i tempi di risposta. Sulle strade condivise serve poi un vigile, chiamato arbitro del bus, che assegna il turno quando due dispositivi vogliono parlare insieme, e curiosamente le periferiche hanno di solito la precedenza sul processore, perché un disco in movimento o una tastiera che batte attendono con riluttanza, mentre la CPU può sopportare una pausa. L'erede moderno di queste strade è il PCI Express, che ha abbandonato il bus parallelo condiviso in favore di tante corsie seriali punto a punto, cioè strade dedicate tra due soli interlocutori che viaggiano molto più in fretta, e che collega oggi schede video, dischi veloci e schede di rete alla scheda madre.
Tutti questi componenti trovano casa nella scheda madre, la grande scheda di circuito stampato che occupa il fondo del case e che potremmo paragonare a una città, con lo socket, cioè lo zoccolo, riservato al processore, gli alloggiamenti per i moduli di memoria, il chipset, l'insieme dei chip che coordinano i quartieri, e i connettori che portano l'energia e collegano dischi e schede aggiuntive, perché ogni abitante ha bisogno della sua via d'accesso.
L'immagine qui sopra mostra una scheda madre vera, con le etichette che indicano lo zoccolo del processore, gli alloggiamenti dei moduli di memoria, i connettori per le schede di espansione e i chip d'accompagnamento, e noti che ogni pezzo ha il suo quartiere e le sue strade. Dentro lo zoccolo di un computer recente vive quasi sempre un processore multicore, cioè un chip che raccoglie più nuclei, ognuno un processore completo con i propri registri e la propria unità di controllo, che si dividono il lavoro come cuochi nella stessa cucina, mentre l'orologio che scandisce questa sinfonia batte più di un miliardo di volte al secondo.
Il chipset della scheda madre merita una parola in più, perché è il municipio della città, e un tempo si divideva in due edifici, il ponte nord, vicino al processore, che gestiva le strade veloci verso la memoria e la scheda grafica, e il ponte sud, che raccoglieva le strade lente verso dischi, tastiere e altre periferiche, mentre oggi gran parte delle sue funzioni è rientrata dentro il processore stesso o in un unico chip compagno. Sulla scheda madre trovano posto anche molte periferiche integrate, cioè dispositivi interi saldati sulla scheda anziché aggiunti a parte, come la scheda audio, la scheda di rete e i controllori per le porte USB, e qui avviene anche il momento più solenne della giornata del computer, l'avvio, che conviene raccontare per sommi capi perché sarà il filo conduttore del modulo sui sistemi operativi. Quando premi il bottone di accensione, un piccolo programma custodito in un chip di memoria, chiamato firmware e conosciuto storicamente come BIOS, oggi spesso con il nome più moderno di UEFI, esegue dapprima un controllo di salute chiamato autodiagnosi all'accensione, verifica la memoria e i dischi, poi va a cercare su un disco un piccolo programma caricatore, e quest'ultimo tira su il sistema operativo vero e proprio, che a quel punto prende in mano la casa e inizia a servire te, e tutto ciò che avviene da quel momento in poi è software, l'argomento del prossimo gradino del percorso.
Lo zoccolo, poi, custodisce meraviglie che valgono una visita guidata. Molti processori recenti praticano l'iperthreading, chiamato hyperthreading nei documenti tecnici, che consiste nel dotare ogni nucleo di due insiemi di registri e di due file di lavoro affiancate, così che il nucleo alterni due programmi a ritmo serrato e tenga le sue catene di montaggio piene anche quando uno dei due sta aspettando la memoria, un po' come un cuoco che gestisce due teglie passando dall'una all'altra nei tempi morti. Accanto al processore principale lavora spesso un processore grafico, la GPU, sigla di Graphics Processing Unit, un coprocessore nato per disegnare immagini e dotato di migliaia di unità di calcolo semplici che lavorano in parallelo come una brigata di pittori, e che oggi viene prestato volentieri anche ai calcoli scientifici, perché certi problemi si risolvono benissimo dividendoli in migliaia di pennellate contemporanee, e accanto a questi troviamo altri coprocessori specializzati per la rete, per i suoni e per la crittografia, una corte al servizio del sovrano.
Veniamo infine ai numeri che i negozi scrivono in vetrina, e alla promessa di leggerli con occhio critico. Dire che un processore lavora a tre gigahertz significa dire che il suo metronomo batte tre miliardi di volte al secondo, e nulla di più, perché a parità di battiti contano anche quante istruzioni riesce a completare a ogni battito, una grandezza che dipende dalla profondità della catena di montaggio, dalle previsioni dei salti, dalla capacità delle cache e da mille altri dettagli d'officina, e per questo due macchine con lo stesso numero di gigahertz possono correre a velocità assai diverse. C'è poi un freno fisico che tiene a bada la corsa, il consumo, perché salire di frequenza costa energia e disperde calore, e i chip che scaldano troppo devono essere raffreddati con ventole sempre più impegnative, ragione per cui i portatili e i telefoni preferiscono molti nuclei a frequenze modeste, una flotta di operai disciplinati anziché un campione affamato, e la durata della batteria ne guadagna.
Come si misura allora la bravura di una macchina, domanda giusta per chi vuole comprare o semplicemente capire? Il modo più antico è il conteggio dei MIPS, cioè dei milioni di istruzioni al secondo completate, un numero comodo ma ingannevole, perché istruzioni diverse pesano in modo diverso e lo stesso programma si traduce in conteggi diversi su vocabolari diversi, e per questo gli esperti si affidano ai benchmark, suite di programmi reali, come quelle della famiglia SPEC, sui quali si fanno correre le macchine candidate misurando il tempo impiegato, ottenendo così un confronto onesto basato su compiti concreti. La regola d'oro, quando qualcuno ti vanta una cifra isolata, è chiedere sempre su quale lavoro è stata misurata, perché un computer, come un'auto, può vincere in salita e perdere in autostrada, e il confronto serio nasce da programmi reali, dati uguali e condizioni uguali, il terreno piano su cui le macchine si sfidano alla pari.
La teoria per oggi è servita, e ora indossiamo il grembiule, perché queste idee diventano solide soltanto quando le provi con le mani. Gli esercizi che seguono, sei in tutto e ordinati dal più semplice al più articolato, ti chiedono solo carta, penna, un browser e il computer che hai davanti, e ti faranno compiere a passo lento gli stessi movimenti che la macchina ripete dentro il suo chip, così che quando la sentirai ronzare sul tavolo potrai immaginare con precisione cosa accade nei suoi circuiti.
Il primo riscaldamento è quasi un gioco di voce, e consiste nel contare in binario da zero a quindici, a voce alta oppure su un foglio, scrivendo 0000, 0001, 0010, 0011 e proseguendo fino a 1111, prestando attenzione alle colonne. Ti accorgerai che il riporto che nel modulo scorso faceva traboccare il sommatore vive anche qui, perché ogni volta che una colonna si riempie di uni il suo contenuto si azzera e riversa un uno sulla colonna a sinistra, esattamente come da noi il nove, quando aumenta di uno, riversa un dieci nella posizione seguente. Se ripeterai il gioco con calma, più volte, la scrittura dei numeri in binario smetterà di sembrarti un codice segreto e diventerà un gesto familiare.
Il secondo esperimento ti chiede di aprire una pagina web qualsiasi e di osservare come i colori si scrivano nel linguaggio della macchina, perché ogni tonalità che vedi è in realtà un numero mascherato, scritto con un cancelletto seguito da sei cifre, per esempio #FF0000, dove le prime due cifre dicono quanto rosso, le due di mezzo quanto verde e le ultime due quanto blu. La coppia FF vale duecentocinquantacinque, il massimo che un byte possa contenere, perché ogni cifra esadecimale vale fino a quindici e quindici volte sedici più quindici fa duecentocinquantacinque, e da qui puoi decifrare da solo #00FF00, che è il verde pieno, #0000FF, che è il blu pieno, #FFFFFF, che è il bianco ottenuto accendendo tutto, e #000000, che è il nero ottenuto spegnendo tutto, e scrivendo a mano una decina di queste ricette capirai nel palmo della mano come sedici simboli bastino a raccontare un byte.
Il terzo esperimento è il mio preferito e lo chiamo il processore umano, e ti servono un foglio, una matita e un po' di pazienza. Disegna in alto tre riquadretti e scrivici sopra i nomi A, B e C, che saranno i tuoi registri, poi sotto disegna otto celle numerate da zero a sette, che sarà la tua memoria, e nelle prime celle scrivi un programma di cinque istruzioni, per esempio carica sette in A nella cella zero, carica sette in B nella cella uno, sottrai B da A e metti il risultato in C nella cella due, se C vale zero salta direttamente alla cella cinque scrivendo questa scelta nella cella tre, carica il numero novantanove in C nella cella quattro, e memorizza C nella cella sette dalla cella cinque. Ora esegui a mano le istruzioni una dopo l'altra, cancellando e riscrivendo con la matita i contenuti dei riquadri dopo ogni passo, e fai attenzione al bivio, perché quando A e B sono uguali il risultato della sottrazione vale zero e il salto fa saltare a piè pari la cella quattro, così nella cella sette finisce lo zero, mentre se carichi nella cella uno un numero diverso, per esempio tre, il salto resta inoperoso e la cella quattro si esegue davvero, depositando novantanove. Riesegui il programma due volte, una per ogni scelta, e avrai appena provato con le dita il potere dei salti condizionali, i bivi che turbano le catene di montaggio dei processori veri.
Il quarto esperimento ti porta dentro la macchina che stai usando davvero, e questa volta la visita
è completa. Se il tuo computer è Linux apri un terminale e digita lscpu, e vedrai
comparire il nome del processore con il numero di nuclei, il numero di thread per ogni nucleo, che
ricorda l'iperthreading dei processori recenti, e la frequenza dell'orologio in megahertz o gigahertz,
poi scorri l'elenco fino alle voci della cache e leggi le dimensioni dei livelli L1d e L1i, dei dati
e delle istruzioni, del livello L2 e del livello L3, confrontandole con la gerarchia che abbiamo
disegnato poc'anzi. Su un Mac trovi le stesse informazioni nella finestra Informazioni di sistema,
mentre su Windows apri il Gestione attività oppure digita msinfo32 nella casella di
ricerca, e in ogni caso annota su un foglietto modello del processore, numero di core, di thread e di
livelli di cache, per confrontarli con quelli del tuo smartphone, che è a sua volta un piccolo von
Neumann da tenere in tasca e che spesso, per numero di nuclei, non ha nulla da invidiare al computer.
Il quinto esperimento riguarda la memoria e il suo doppio fondo. Sempre da terminale Linux digita
free -h e osserva la riga dedicata alla memoria, con il totale, l'usata e la libera,
poi scendi all'ultima riga, quella della swap, cioè dello scambio, e scopri che il computer ha
ricavato una memoria d'emergenza dal disco, lenta come una strada provinciale, su cui appoggia le
cose meno urgenti quando il banco della RAM si riempie, ed è per questo che, quando apri troppi
programmi insieme e la macchina diventa pesante, lei ricomincia a lavorare sul disco e tutto sembra
intruppato. Su Windows trovi la stessa paginazione nel Gestione attività, nella scheda Prestazioni,
accanto alla quantità di memoria fisica, e ti invito a ripetere la lettura dopo aver aperto un
programma pesante come un browser con molte schede, perché vedere i numeri muoversi trasforma la
gerarchia di memoria da disegno su carta in fenomeno visibile.
Il sesto ed ultimo esperimento è il più facile da raccontare e il più istruttivo da guardare, e consiste nell'osservare il tuo computer mentre si sveglia. Al prossimo riavvio, prima che il sistema operativo appaia, ferma lo sguardo sulla prima schermata, dove compare il nome del firmware, il conteggio o il controllo della memoria, il riconoscimento dei dischi, e pensa che in quei secondi la macchina sta eseguendo l'autodiagnosi all'accensione di cui abbiamo parlato, un paziente giro di visite prima di suonare il campanello del sistema operativo. Se la schermata scivola via troppo in fretta, riavvia cercando nel manuale del computer il tasto che apre le impostazioni del firmware, e lì riconoscerai, scritte con parole del mestiere, le strade, gli zoccoli e i quartieri di questa pagina, in attesa del giorno, molto vicino, in cui il caricatore prenderà il testimone e inizierà la storia del software.
Quello che hai letto in questa pagina attinge soprattutto al volume Architettura dei calcolatori di Andrew S. Tanenbaum, il testo della nostra biblioteca che accompagna il percorso, e precisamente al capitolo introduttivo per la storia, le generazioni e la legge di Moore, al capitolo sull'organizzazione dei sistemi di calcolo per il processore, il ciclo di esecuzione, i registri di servizio, le gerarchie di memoria e le cache, al capitolo sui bus per le strade, i loro regolamenti e il PCI Express, al capitolo sull'architettura dell'insieme d'istruzioni per il vocabolario della macchina e per lo scontro tra CISC e RISC, e infine al capitolo sul calcolo parallelo per la pipeline, l'iperthreading, i nuclei multipli e i coprocessori. Ora che sai come è fatta la macchina a livello di hardware, il cammino scende nel cortile del costruttore, perché la prossima pagina smonta il processore pezzo per pezzo e mostra come il ciclo di esecuzione sia organizzato in unità di lavoro che procedono insieme come gli addetti di una lavanderia, quindi prosegui verso la microarchitettura quando ti senti pronto a guardare dentro il motore.