Architettura degli Elaboratori
Transcript
Architettura degli Elaboratori
Architettura degli Elaboratori Copyleft (c) 2014 Emanuele Ferri ([email protected]) Indice generale Digitale e analogico.........................................................................................................................1 Memoria informatica.......................................................................................................................2 Classificazione della memoria....................................................................................................2 Classificazione in base alla modalità di accesso....................................................................3 Classificazione per possibilità di scrittura da parte dell'utente finale....................................4 Classificazione in base alla tecnologia costruttiva.................................................................4 Classificazione per velocità di accesso e costo unitario.........................................................5 Unità di misura............................................................................................................................5 Componenti di un computer............................................................................................................7 Memoria principale.....................................................................................................................7 CPU.............................................................................................................................................8 Unità aritmetico-logica...........................................................................................................8 Istruzione..............................................................................................................................10 Registri.................................................................................................................................10 Unità di controllo..................................................................................................................11 Frequenza.............................................................................................................................11 Dispositivi di input/output........................................................................................................12 Bus............................................................................................................................................14 Indirizzamento......................................................................................................................14 Numeri e sistemi di numerazione..................................................................................................15 Cambiamenti di base.................................................................................................................17 Insiemi numerici.......................................................................................................................20 Digitale e analogico L'attributo digitale viene utilizzato in relazione ad una grandezza/sistema che varia fra un insieme finito di possibili stati in maniera discreta (ogni stato è ben distinto dagli altri). Deriva dal termine inglese digit (cifra). Analogica è, invece, una grandezza (ovvero un sistema) che varia con continuità (questo non significa che non possa esser rappresentata numericamente). La parola deriva dal greco e significa, letteralmente, discorso simile. Tratto da: Digitale o analogico? Un esempio di sistema digitale è il blocco del cambio della macchina: le marce in genere sono 6 più una posizione centrale chiamata "folle", non si può mettere la leva del cambio a metà tra la prima e la seconda. Il volante e l'acceleratore invece sono sistemi analogici in quanto non si muovono a scatti ma con continuità. Altri esempi di un controllo digitale lo troviamo nel phon: in genere il phon può essere spento, erogare una quantità moderata di aria o erogarne molta, quindi è dotato di una levetta che può assumere tre posizioni in coppia con un'altra simile per dosare il calore dell'aria. I tasti della tastiera del computer e i pulsanti dei controller per i videogiochi possono assumere solo due valori (premuto o rilasciato) quindi sono digitali. I testi del telecomando (compreso il volume) possono anch'essi assumere solo due valori mentre il volume dei vecchi televisori veniva regolato tramite una manopola analogica (in molti impianti stereo è ancora così). Fu la Nintendo a creare, per il suo Nintendo 64, il primo controller dotato di "leva analogica", volgarmente detto "tricorno". Tuttavia il segnale viene digitalizzato ancor prima di raggiungere la consolle (c'è una specie di ruota dentata per ognuno dei due assi). Inoltre, anche se Mario su N64 può correre, correre lentamente, camminare e stare fermo, non può certo replicare tutta la gamma di velocità di un essere umano reale. Master Chief (saga di Halo), può spostarsi e mirare in modo molto preciso, tanto che i suoi movimenti appaiono simili a quelli di un essere umano reale. Anche in questo caso, però, si tratta pur sempre di un insieme discreto di possibilità. E' tuttavia vero che noi percepiamo i suoi movimenti come analogici, il modello mentale che usiamo per descriverli è analogico. Parlando di mouse, anche se il movimento è analogico, il campionamento dello spostamento avviene in modo digitale, sia in quelli dotati di pallina che in quelli ad infrarossi. Sono analogici i rubinetti dell'acqua e colonnina di mercurio di un termometro, che sale e scende con continuità. Un dinamometro pesapersone (spesso volgarmente (ed erroneamente) chiamato bilancia) può mostrare il peso tramite una lancetta che si muove con continuità o avere un display che riporta un numero finito di valori e in entrambe la forza peso viene misurata tramite un modello analogico, la legge di Hooke. Un orologio a lancette non necessariamente è analogico: in molti orologi le lancette si muovono a scatti e per fare un giro completo scattano 60 volte, quindi sono digitali. In altri orologi le lancette si muovono in modo fluido, continuo, assumendo valori appartenenti ad una scala virtualmente infinita. Le lampade di casa sono quasi sempre digitali (accese o spente) però ce ne sono alcune (tipo i faretti alogeni) la cui luminosità può essere dosata tramite una manopola o una leva dal movimento continuo. Dopo aver fornito definizioni ed esempi che sembrano chiarire abbastanza bene le caratteristiche dei due sistemi, pongo la seguente domanda: "la clessidra è analogica o digitale"? Certamente, visto da lontano, il fluire della sabbia appare continuo, tuttavia sappiamo bene che avvicinandoci potremmo osservare la caduta dei singoli granelli, un fenomeno discreto. Potremmo utilizzare una sabbia più sottile o renderla sottilissima in modo artificiale ma ciò servirebbe solo ad ingannare un osservatore superficiale. Per quanto sforzi possiamo fare per renderla più sottile, questo processo ha un limite nella struttura atomica della materia. Forse alcuni fenomeni ci appaiono analogici ed il modello che utilizziamo per descriverli è analogico perché la nostra osservazione della realtà è superficiale. Sono considerazioni legittime alle quali però, da informatico, non saprei dare risposte soddisfacenti. Tra i sistemi digitali quello binario è il più semplice in quanto prevede due soli valori. E' il sistema adottato dai moderni computer. Vedremo in seguito il motivo. Memoria informatica In ambito informatico la memoria è la parte del computer destinata a conservare informazioni per un certo periodo di tempo. La memorizzazione di informazioni in memoria, e il successivo recupero delle medesime, sono funzioni fondamentali nel funzionamento del computer. Tratto da Memoria Informatica Classificazione della memoria Sulla pagina di Wikipedia troviamo una classificazione della memoria molto dettagliata che va studiata e compresa. Mi preme sottolineare che lo ritengo un aspetto fondamentale, su cui purtroppo si fa spesso parecchia confusione. Vorrei ribadire alcuni contenuti di quella pagina. Viene spesso dato per scontato che la memoria di un computer sia un dispositivo elettronico o magnetico. In genere è vero, però bisogna fare le dovute precisazioni. Le schede perforate, che hanno conosciuto una larga diffusione anche in epoche relativamente recenti (fino ai primi anni '80), sono memorie informatiche a tutti gli effetti eppure non sono elettroniche né magnetiche: sono pezzi di cartone con dei buchi. Questo discorso serve a ribadire il concetto che, se da un lato è assodato che l'informatica deve il suo enorme successo all'evoluzione incalzante dell'elettronica, d'altro, a livello teorico, non è molto importante il modo con cui vengono implementati certi meccanismi hardware. Un'altra considerazione andrebbe fatta sulla natura analogica o digitale delle memorie. Secondo me (è un parere alquanto opinabile di una persona con poche competenze a riguardo) non è tanto la memoria ad essere digitale o analogica, quanto piuttosto il modo in cui viene usata. Fornisco un esempio che, come al solito, vale più di mille parole. Il mio primo computer fu un VIC-20, il secondo un Philips VG 8020, un computer conforme allo standard MSX. Entrambi i computer potevano utilizzare delle comuni musicassette come memorie di massa. La musicassetta fu inventata per registrare musica in analogico ma, grazie alla sua diffusione ed economicità, ben presto venne impiegata anche per registrare dati e programmi in digitale. D'altro canto esistono dispositivi utilizzati da sempre in modo digitale, come gli hard disk che, in linea teorica (finora credo non sia mai stato fatto) sono leggibili tramite una strumentazione analogica. Ciò potrebbe permettere di ricostruire il contenuto precedente ad una sovrascrittura. Per ora sarà anche fantascienza ma ci aiuta a capire che non è tanto il dispositivo ad essere analogico o digitale quanto il modo in cui viene utilizzato. Dd - Destroyer of Disks Certamente per alcuni supporto un utilizzo analogico sarebbe alquanto bizzarro. Si pensi per esempio alle sopracitate schede perforate. Usarle in modalità analogica significherebbe misurare la dimensione dei buchi. E' evidente che nessuno lo ha mai fatto e, presumo, nessuno mai lo farà. Vi sono molti modi per classificare la memoria (vedere la pagina di Wikipedia per ulteriori approfondimenti): Classificazione in base alla modalità di accesso Ad un dispositivo di memorizzazione si può accedere sostanzialmente in tre modi (nell'articolo ne vengono riportati solo due ma altrove Wikipedia li distingue ulteriormente). Accesso sequenziale significa che per leggere o scrivere il dato che mi interessa devo prima scorrere (e magari leggere) i dati che stanno tra di esso e la testina di lettura/scrittura. Un esempio classico sono i nastri magnetici (le musicassette per esempio). Un modo per trovare la canzone è ascoltare ogni tanto premendo play e, in base ad un indice delle canzoni (su carta o nella mia testa) andare avanti o indietro coi tasti fast-forward e rewind. Un celebre esempio di accesso sequenziale è il nastro delle macchine di Turing in cui la testina si muove sul nastro solo di una posizione alla volta e per capire dove si trova legge il nastro. Nelle memorie ad accesso diretto invece si può "saltare" da una locazione all'altra fornendo un indirizzo. Nelle memorie ad accesso diretto il tempo per accedere ai dati non è costante ma dipende dall'indirizzo di memoria a cui è avvenuto l'accesso precedente. In ambito informatico l'esempio più comune di memoria ad accesso diretto è l'hard disk. Negli hard disk la lettura e la scrittura avvengono per settori (la minima porzione di disco leggibile e scrivibile, tipicamente di 512 byte). Ogni settore è numerato. Per accedere al settore basta specificare il suo indirizzo numerico. E' molto importante notare che negli hard disk il tempo di accesso dipende dalla posizione corrente delle testine rispetto al settore a cui si vuole accedere: se il settore è vicino il tempo di accesso è basso, se è lontano alto. Ciò è dovuto alla natura in parte meccanica degli hard disk. I dischi girano, tutti insieme, velocissimi, e le testine si spostano avanti e indietro, tutte insieme, vicinissime alla superficie dei dischi. Questi spostamenti richiedono più tempo se la strada da percorrere è lunga, meno se è breve. Anche nelle memoria ad accesso casuale, dette RAM (Random Access Memory) si salta da una locazione all'altra in base all'indirizzo fornito ma il tempo di accesso è costante, ossia, il tempo impiegato per raggiungere la locazione desiderata è sempre lo stesso. Esempi di memorie ad accesso casuale sono le DDR SDRAM presenti nella maggioranza dei computer attuali. Per chiarire meglio questi concetti prendiamo come esempio un televisore (non è una memoria ma rende l'idea). Se uso i tasti dei canali presenti sul telecomando, il tempo impiegato per cambiare canale è costante, non dipende dal canale che voglio guardare né da quello che sto guardando. Potrei però adottare anche un accesso sequenziale tramite i tasti "canale precedente" e "canale successivo". In quel caso, per arrivare al canale che mi interessa in genere dovrò visionarne molti altri. In questo caso l'accesso sequenziale è una limitazione in quanto la natura dell'accesso ai canali è certamente casuale. Classificazione per possibilità di scrittura da parte dell'utente finale La tipica memoria può essere sia letta che scritta. Questi dispositivi sono detti memorie a letturascrittura. Tuttavia sono utilizzate anche memorie che vengono scritte solo in fase di inizializzazione, e per le quali non è possibile la scrittura nell'uso normale. Tale inizializzazione può essere effettuata in modo incrementale dalla stessa apparecchiatura con cui vengono riletti i dati scritti. Questi dispositivi sono detti memorie scrivibili una sola volta, o WORM (Write Once, Read Many). Alternativamente, può essere necessario scrivere tutti i dati con un'apposita apparecchiatura esterna prima di poter usare la memoria in lettura. Questi dispositivi sono detti memorie a sola lettura, o ROM (Read-Only Memory). Ecco gli esempi più diffusi per ognuno dei tre suddetti tipi: Memorie a lettura-scrittura: memorie DDR, memorie EPROM, memorie EEPROM, dischi ottici CD-RW, dischi ottici DVD-RW, memorie elettroniche flash, nuclei di ferrite, dischi rigidi, floppy disk, dischi magneto-ottici RW. Memorie scrivibili una sola volta: carta con penna a inchiostro indelebile, dischi magneto-ottici WORM, dischi ottici CD-R, dischi ottici DVD-R, memorie elettroniche PROM, memorie elettroniche OTPROM. Memorie a sola lettura: carta stampata, memorie elettroniche ROM, dischi ottici CD-ROM, dischi ottici DVD-ROM. (Tratto da www.wikipedia.it) Classificazione in base alla tecnologia costruttiva Come già accennato le memorie possono essere fatte di materiali differenti. La solita pagina di Wikipedia fornisce lo spunto per una classificazione anche in base a questo aspetto. Senza addentrasi nei dettagli, è utile per capire il concetto più di molte spiegazioni. La classificazione non pretende di essere precisa né tantomeno esaustiva. Memoria cartacea Scheda perforata Nastro perforato Memoria elettronica DRAM SRAM Memoria a stato solido Memoria magnetica Memoria a nucleo magnetico Nastro magnetico Musicassetta VHS (Video Home System) Disco magnetico Floppy disk Hard disk Zip drive Memoria ottica Disco ottico CD (Compact Disc) DVD (Digital Versatile Disc) BD (Blue-ray Disc) Memoria olografica Da notare che le musicassette e le VHS non sono nate come memorie informatiche bensì per contenere rispettivamente musica e video in formato analogico. Tuttavia, come già accennato in precedenza, sono state usate anche per archiviare dati in digitale. Consiglio di dare una occhiata a questa pagina: Supporti-di-memoria. In essa viene elencata una moltitudine di memorie informatiche con immagini e brevi descrizioni. Molte di queste memorie non hanno avuto grande successo. Io ne ho riconosciute solo alcune. Classificazione per velocità di accesso e costo unitario Per le memorie a lettura-scrittura, il tempo di lettura è normalmente vicino al tempo di scrittura, per cui si parla genericamente di tempo di accesso. Per le memorie scrivibili una sola volta, la scrittura può essere molto più lenta della lettura; in tal caso, dato che la memoria verrà letta molte volte, si considera come più significativo il tempo di lettura. In generale, il costo unitario (cioè per byte) delle memorie cresce al crescere della velocità di lettura. Pertanto, la classificazione per velocità di lettura coincide sostanzialmente con la classificazione per costo unitario. (Tratto da Wikipedia) Unità di misura Non tutte le memorie sono digitali. I vecchi vinile, le musicassette usate per registrare musica e le videocassette per i filmati, sono memorie usate per decenni in analogico. Le musicassette e persino le videocassette, come scritto precedentemente, si possono usare anche in digitale, per salvare dati e programmi. Se provate a fare la copia di un file, poi la copia della copia, la copia della copia della copia, …, l'ultima copia sarà esattamente uguale all'originale. Se provate a copiare una musicassetta (con un semplice mangiacassette a doppia piastra), a copiare la copia, a copiare la copia della copia della copia, … il risultato finale sarà decisamente differente dall'originale, una differenza facilmente percepibile con l'udito, senza ricorrere a sofisticate strumentazioni. Questo è uno dei motivi del graduale abbandono della memorizzazione analogica a favore di quella digitale. Ancor oggi, non tutte le memorie sono digitali. I calcolatori però usano sempre e solo memorie digitali. Tuttavia non è però vero che abbiano sempre usato memorie binarie. Le memorie moderne, in genere, lo sono, ma è probabile che la macchina analitica di Babbage e l'Eniac, dato che adottavano il sistema decimale per eseguire i calcoli, possedessero memorie digitali decimali. Non si deve dimenticare che tali macchine, come la maggioranza dei primi computer, erano state ideate principalmente per eseguire calcoli. Gli esseri umani sono abituati ad utilizzare dieci cifre per scrivere i numeri e si aspettano di fornire in ingresso (input) numeri scritti in decimale e di ottenere in uscita (output) numeri scritti in decimale. Lavorare in decimale evita di effettuare due conversioni, da decimale a binario e da binario a decimale per comprendere l'input e rendere comprensibile l'output. Purtroppo, come vedremo più avanti, usare un sistema decimale per eseguire i calcoli, aumenta enormemente la complessità della macchina. Più che i ripensamenti, i problemi economici e gli attriti meccanici, forse è stato questo il vero motivo del parziale fallimento di Babbage. Esistono memorie cartacee, magnetiche, elettroniche. Esistono memorie ad accesso sequenziale, diretto, casuale. Ne esistono di leggibili e scrivibili e di solo leggibili. Ne esistono di costose e veloci e di economiche e lente. Esistono moltissimi tipi di memorie informatiche. Eppure, da un punto di vista astratto, più o meno tutte si possono rappresentare come una sequenza finita di soli due valori, che siamo soliti chiamare 0 ed 1 (ma falso e vero, no e si, nero e bianco, spento e acceso, male e bene, yin e yang, … andrebbero altrettanto bene). L'unità elementare dell'informazione, in grado di assumere due soli valori, viene detta bit. Il simbolo del bit è la lettera b minuscola. In memorie che utilizzano una tecnologia costruttiva diversa dalla carta è difficile immaginare un bit ma se per esempio prendiamo una scheda perforata, il bit coincide col pezzettino di cartone che può essere forato o lasciato intatto. Anche se il bit è l'unità elementare dell'informazione, generalmente, quando si parla di memorie, si usa un'altra unità di misura, detta byte. Il simbolo del byte è la lettera B maiuscola. Un byte è una sequenza di bit ossia un certo numero bit messi in fila. In genere, oggi, il numero di bit che formano un byte è 8, ma in passato non è sempre stato così. Byte deriva dalla parola inglese bite, che significa boccone, morso. E' la più piccola quantità di memoria che può essere letta o scritta (“addentata”). Il perché non sia il caso di “addentare” il singolo bit verrà spiegato in seguito. Volendo rappresentare schematicamente un byte verrebbe fuori una cosa del genere: yin yin yang yang yin yin yin yang Non ho usato 0 e 1 volutamente, altrimenti qualcuno potrebbe pensare che le memorie dei computer contengano solo dati numerici. Le memorie dei computer sono formate di byte, composti a loro volta da certo numero di bit (generalmente 8). Non necessariamente il contenuto di un byte rappresenta un numero: potrebbe rappresentare il codice operativo di una istruzione di un programma (si vedrà in seguito), un carattere o chissà cos'altro. Se proprio ci teniamo a conformarci al sistema lo possiamo vedere in questo modo: 0 0 1 1 0 0 0 1 Una piccola memoria binaria (5 byte), qualunque sia la sua tecnologia costruttiva, la sua modalità di accesso etc., la possiamo immaginare così 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 0 0 0 0 1 1 1 1 Gli 0 e gli 1 sono stati messi a caso, non significano niente. Chiaramente le memorie vere possono avere dimensioni enormemente maggiori. Per questo motivo, per indicarne la dimensione, vengono utilizzati i prefissi del Sistema Internazionale di unità di misura, gli stessi che si usano nella fisica, per pesare frutta e verdura, per calcolare la strada fatta in bicicletta etc. Poiché le memorie non saranno mai un sottomultiplo di un byte, i prefissi che ci interessano sono quelli ad esponente positivo. Per ora in genere non si supera il tera, almeno nell'hardware alla nostra portata (da non molto esistono in effetti in vendita hard disk da circa un terabyte (TB). k M G kilo 103 mega 106 giga 109 T tera 1012 Maiuscole e minuscole fanno una enorme differenza. Per esempio m sta per milli, ossia un millesimo, mentre M sta per mega, ossia un milione di volte. Purtroppo il prefisso di kilo è k (minuscolo) in quanto K (maiuscolo) significa kelvin (unità di misura della temperatura). Relativamente alle memorie abbiamo dunque: kB kilobyte 103byte MB megabyte 106byte GB gigabyte 109byte TB terabyte 1012byte Come abbiamo visto in precedenza, non tutte le memorie hanno la stessa velocità. Per ora prenderemo in esame solo la velocità di trasferimento ossia di lettura o di scrittura (faremo finta che siano abbastanza simili) ma per esempio l'hard disk prima di cominciare trasferire dati, deve posizionare le testine, girare i dischi etc. Se la velocità di un veicolo di misura in metri al secondo (m/s) ovviamente la velocità di una memoria si misurerà in byte al secondo (B/s). I dati che seguono sono relativi ad una veloce ricerca effettuata il 3 novembre 2010. Per dare una idea (i dati sono puramente indicativi e variano molto da dispositivo a dispositivo), un hard disk meccanico molto veloce avrà una velocità di trasferimento dati (vedremo meglio in seguito cosa significa) di 100MB/s, una memoria DDR3 (in dual channel*) potrebbe superare i 20000MB/s, ossia 200 (DUECENTO) volte tanto!!!! Non sono molto aggiornato sui prezzi dell'hardware nuovo ma una breve ricerca mi ha permesso di trovare un banco di DDR3 da un 2GB ad una ventina di euro ed un hard disk meccanico da 1000GB a circa 45 euro. Il prezzo della DDR3 si aggira quindi intorno a 10 euro al GB mentre il prezzo di un hard disk meccanico sui 5 centesimi di euro al GB. Il costo della DDR3 è circa 200 (DUECENTO) volte maggiore. Componenti di un computer La maggioranza dei moderni computer deriva dal modello adottato da Von Neumann per realizzare alcuni dei primi calcolatori elettronici. A questo schema di progettazione viene solitamente attribuito il nome di architettura o modello di Von Neumann (anche se il modello originario è in realtà leggermente differente). Esistono altri modelli, come per esempio il modello Harvard. I moderni computer, pur basandosi grosso modo sul modello di Von Neumann, magari adottano anche soluzioni interne più simili al modello Harvard. Quella che segue è una descrizione delle componenti e delle relative caratteristiche presenti nella maggior parte dei computer recenti. Può essere che alcune di queste caratteristiche non fossero effettivamente presenti nelle idee originarie di Von Neumann. Memoria principale I moderni computer sono dotati di una memoria digitale, binaria e ad accesso casuale in cui, secondo il modello di Von Neumann, trovano posto sia dati sia i programmi in esecuzione. Tale memoria prende il nome di memoria principale (o centrale). Da notare che esistono anche architetture, come per esempio l'architettura Harvard, in cui programmi e dati si trovano in memorie fisicamente distinte (funzionano così alcune memorie cache). Il fatto che programmi e dati condividano la stessa memoria fisica permette di assegnare più o meno spazio agli uni o agli altri a seconda delle necessità. Essendo una memoria ad accesso casuale, si ha la possibilità di indirizzare (indirizzare è un po' come chiamare un giocatore col numero della maglia) una certa quantità di bit (generalmente 8). Tale quantità, come già detto, prende il nome di byte. Riprendendo l'esempio già visto in precedenza abbiamo: 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 2 0 1 0 1 0 0 1 0 3 0 0 1 0 1 1 1 0 4 0 0 0 0 1 1 1 1 Nella prima colonna di sinistra, in grassetto, sono riportati gli indirizzi dei byte. Siccome nella maggioranza delle moderne architetture, più o meno tutto è reso col sistema binario, tanto vale scrivere anche gli indirizzi con il sistema di numerazione binario: 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 10 0 1 0 1 0 0 1 0 11 0 0 1 0 1 1 1 0 100 0 0 0 0 1 1 1 1 Vedremo meglio in seguito il sistema di numerazione binario. Per ora basti sapere che le cifre che formano i numeri sono due, 0 e 1 (nel sistema decimale sono dieci) e che l'algoritmo (il procedimento) adottato per generare i simboli dei numeri a partire dalle cifre è lo stesso del sistema decimale. Vorrei ribadire alcuni concetti. Gli indirizzi dei byte hanno un ordinamento (10 viene prima di 100), si possono sommare (10+1=11) sottrarre etc. Insomma, senza scomodare Cantor e la teoria degli insiemi, è evidente che gli indirizzi dei byte sono proprio dei numeri. Al contrario i valori assunti dai singoli byte, non necessariamente sono numerici. Come già accennato precedentemente, un byte potrebbe contenere un numero, parte di una istruzione, un carattere, … CPU La CPU (central processor unit, unità centrale di elaborazione) è quella componente del calcolatore che esegue i programmi contenuti nella memoria. Un programma si potrebbe definire come un insieme ordinato (un elenco) di istruzioni mediante il quale la macchina viene istruita a svolgere compiti di varia natura. Le istruzioni possono essere operazioni aritmetiche, logiche e di confronto, letture e scritture in memoria, salti, operazioni di input (letture dalla memoria centrale) e di output (scritture in memoria centrale). Spesso ci si riferisce alla CPU col termine processore, anche se nelle moderne architetture esistono anche processori grafici, detti GPU (Graphics Processor Unit) ed altri processori dedicati. Unità aritmetico-logica All'interno della CPU trova posto la ALU (arithmetic logic unit, unità aritmetico logica). Si può immaginare la ALU come una calcolatrice un po' particolare in grado di eseguire, oltre ad operazioni aritmetiche, anche operazioni logiche e di confronto. Vedremo meglio in seguito in cosa consistono tali operazioni: per ora basti sapere che, mentre le operazioni aritmetiche operano su numeri e restituiscono numeri, quelle logiche operano su valori di verità (falso e vero) e restituiscono valori di verità. Le operazioni di confronto operano su numeri e restituiscono valori di verità. Le ALU di diversi modelli di processore possono differire molto, per il modo in cui sono costruite e per le operazioni che sono in grado di eseguire. Quello che è importante capire è che, sebbene la ALU manchi di alcune operazioni (e dato che le funzioni matematiche sono una infinità (più che numerabile) è evidente che una infinità di funzioni manca), tuttavia è possibile programmare molte di quelle assenti. Per esempio, supponiamo di avere una ALU capace di fare solo la somma tra numeri interi. Con un semplice programma è facile ottenere anche la moltiplicazione e persino l'elevamento a potenza. Segue l'esempio in Ruby ma si sarebbe potuto utilizzare qualsiasi linguaggio Turing-equivalente: def prodotto(x,y) i=0 p=0 while i<y p=p+x i=i+1 end return p end def potenza(x,y) i=0 p=1 while i<y p=prodotto(p,x) i=i+1 end return p end puts potenza(gets.to_i,gets.to_i) Un computer è capace di eseguire alcune operazioni direttamente via hardware, grazie alla ALU. Tuttavia, a differenza di una calcolatrice, che può eseguire solo le operazioni per cui è stata progettata, un computer è programmabile, può essere cioè istruito ad eseguire una enormità di altre operazioni, partendo dalle poche che la ALU è in grado di eseguire nativamente. Quelle operazioni che non sono eseguibili direttamente dall'hardware (via hardware) sono eseguibili tramite software (via software). Anche coi processori video accade qualcosa di simile. Soprattutto in passato vi erano giochi per pc giocabili anche senza costose schede video. Tuttavia, chi voleva godersi appieno i propri titoli preferiti ed aveva i soldi per farlo, acquistava una scheda video accelerata. Anche i poveretti senza una scheda video “da gioco” potevano giocare ma per loro a parità di risoluzione, tutto girava molto più piano. Ciò che la scheda video faceva grazie al suo hardware dedicato poteva comunque essere fatto (più lentamente) dal software. Il problema insomma non è tanto cosa un computer è in grado di fare ma quanto in fretta riesce a farlo. N.B.: quello che ho appena affermato sarebbe perfettamente vero se i computer potessero disporre di memorie infinite, in realtà, poiché il quantitativo massimo di memoria indirizzabile dipende dall'architettura, ci sono effettivamente dei compiti eseguibili da un computer che per altri computer sono impossibili. Le macchine di Turing, pur essendo estremamente semplici, sono in grado di risolvere gli stessi problemi scientifici risolvibili da un supercalcolatore e di far girare (se fossero equipaggiate coi dovuti dispositivi di input e di output) il più moderno sparatutto in soggettiva. Tuttavia, nel tempo impiegato per fornire i calcoli richiesti, l'essere umano potrebbe estinguersi o colonizzerebbe nuovi mondi mentre il moderno sparatutto, nella migliore delle ipotesi diventerebbe un gioco di strategia, nella peggiore sarebbe vecchio prima ancora di accedere al menù delle opzioni. Istruzione Si accennava al fatto che, nell'architettura di Von Neumann, vi è una sola memoria che contiene sia i dati che le istruzioni ma non è stato spiegato il significato di istruzione. Detto in parole semplici, una istruzione è una sequenza di byte (uno o più) che dice al processore quale operazione compiere e con quali valori. Per esempio, si può immaginare che una istruzione fatta in questo modo 10101010 00000001 00000010 00000111 stia dicendo al processore di sommare (10101010) il numero 1 (00000001) al numero 2 (00000010) e di mettere il risultato nell'indirizzo di memoria 7 (00000111). E' importante tenere presente che questo è solo un esempio inventato per dare una idea di massima del significato di istruzione. E' un esempio semplice da capire ma per certi versi abbastanza anomalo. Il fatto che il primo byte significhi proprio somma è una scelta del tutto arbitraria. Il primo byte dell'esempio è detto codice operativo, gli altri tre prendono il nome di operandi. Tra gli operandi, i primi due sono costanti, il terzo è l'indirizzo di una locazione di memoria il cui contenuto può cambiare (una variabile). Ci sono anche istruzioni che fanno riferimento a sole locazioni di memoria. Per esempio, nella nostra architettura immaginaria ci potrebbe anche essere una istruzione che somma il contenuto di due locazioni di memoria e mette il risultato in una terza locazione. Nei processori reali, tuttavia, in genere una istruzione contiene al massimo un riferimento alla memoria. Registri I registri sono delle piccole memorie interne alla CPU. Quando viene eseguita una operazione aritmetica, gli operandi vengono caricati in registri e il risultato del calcolo viene anch'esso inserito in un registro. I calcoli dunque non vengono eseguiti operando direttamente su locazioni di memoria e il risultato non è inserito immediatamente in una locazione di memoria ma sempre attingendo a registri e scrivendo in registri. Generalmente una architettura è detta ad n bit quando è di n bit la larghezza standard di una variabile semplice, per esempio (ma non solo) un numero intero. Generalmente questo si riflette sulla dimensione dei registri della CPU, anche se non tutti i registri hanno necessariamente quella dimensione. Utilizzare interi da 8 bit significa avere a disposizione 256 valori (2^8), da 0 a 255 se non si usa segno, da -128 a 127 se si utilizza il segno. Se fosse necessario operare su numeri più grandi è sempre possibile farlo in più passaggi, a discapito però della velocità del calcolo. Utilizzare interi a 16 bit invece significa disporre di 65536 valori (2^16), da 0 a 65535 se si rinuncia al segno, da -32768 a 32767 se si utilizza il segno. Anche in questo caso, se fosse necessario operare su numeri di dimensioni maggiori è sempre possibile farlo in più passaggi. Diversi modelli di processore possono avere un numero diverso di registri di diversa grandezza ma con funzioni simili. Vi sono alcuni registri presenti, con piccole differenze, in quasi tutte le architetture, come per esempio il program counter, che contiene l'indirizzo corrente del programma in esecuzione, l'instruction register, che contiene il codice operativo dell'istruzione corrente, il memory address register che indica l'indirizzo della locazione di memoria a cui si vuole accedere, …. Unità di controllo L'unità di controllo è una parte del processore adibita all'esecuzione dei seguenti compiti: 1) Fetch: Consiste nel prelevamento dalla memoria del codice operativo dell'istruzione. Il codice operativo viene caricato nell'instruction register). 2) Decode: Consiste nella decodifica del codice operativo. Per esempio, se l'istruzione è una somma, la ALU viene impostata per eseguire una somma, se è un salto ad un indirizzo assoluto, la ALU non viene proprio usata, … . 3) Operand assembly: Consiste nel prelevamento degli operandi. Per esempio, se l'istruzione è una somma tra due costanti, vengono prelevate dalla memoria le due costanti, se la somma ha tra i suoi operandi una locazione di memoria, prima si preleva l'indirizzo della locazione, poi il contenuto. Notare come questa fase possa variare molto in relazione al codice operativo dell'istruzione. La maggioranza delle architetture moderne sono dotate di registri generali in cui spesso vengono caricati gli operandi (da sommare, sottrarre, …) e scritto il risultato dell'operazione svolta (nel procesore 8086, l'antesignano dei moderni processori per pc, questi registri si chiamano AX, BX, CX, ...) 4) Execute: Consiste nell'esecuzione dell'istruzione. Se l'operazione è un salto verrà effettuato il salto, se è una somma verrà eseguita la somma, … . Il risultato dell'operazione finisce anch'esso in un registro. 5) Store: Consiste nella scrittura del risultato nella memoria centrale. In questa fase il contenuto di un registro (in cui magari, nella fase di execute, era finito il risultato di una operazione aritmetica) viene copiato in una locazione della memoria centrale. La fase di store non è presente in tutte le istruzioni. Il risultato potrebbe benissimo restare in un registro, pronto per essere usato da una istruzione successiva, senza essere scritto nella memoria centrale, in modo da limitare gli accessi alla memoria. Terminato il ciclo di una istruzione, si passa all'istruzione successiva. Frequenza La frequenza indica quante volte si verifica un evento in un certo intervallo temporale. Per esempio, il pistone di una moto può girare 10.000 volte al minuto, un bravo dattilografo può eseguire 240 battute al minuto, in un televisore crt (modello a tubo catodico) l'immagine viene disegnata 50 (PAL) o 60 (NTSC) volte al secondo (però alternando le righe pari a quelle dispari), un essere umano a riposo in genere ha poco più di 60 battiti al minuto (circa uno al secondo). L'unità di misura della frequenza è l'hertz e si indica con il simbolo Hz. Un Hz indica quante volte si verifica un certo evento in un secondo, quindi la sua unità dimensionale è 1/s o equivalentemente s-1. Il pistone di una moto gira a circa 167 Hz, un bravo dattilografo scrive a 4 Hz, lo standard televisivo PAL ha una frequenza di refresh di 50 Hz mentre NTSC di 60 (entrambi interlacciati) e il cuore a riposo batte a circa 1 Hz. Normalmente ci immaginiamo che il tempo fluisca in modo continuo ma non sono a conoscenza delle moderne teorie fisiche e non saprei dire se è stato ipotizzato qualcosa di simile a un “atomo temporale”, una quantità di tempo indivisibile. Ho sempre considerato il tempo come una quantità analogica e la fisica che ho studiato me l'ha mostrato così. Nei computer è diverso. Nei computer tutto è discreto, digitale, persino il tempo. Le istruzioni vengono processate con una certa cadenza temporale. Immaginate una fabbrica di cioccolatini: per essere ultimato il cioccolatino deve passare vari stadi produttivi e il suo movimento su nastro è “scattoso” perché deve fermarsi sotto a certi macchinari, per esempio per essere ricoperto di glassa. Come per i cioccolatini, anche le istruzioni devono passare attraverso delle fasi per essere ultimate (le fasi del ciclo macchina) ed ogni fase richiede un certo quanto temporale (uno o più) indivisibile, un atomo di tempo detto “ciclo di clock”. Come il pianista che suona seguendo il ritmo scandito dal metronomo, un circuito nel processore, chiamato generatore di clock, scandisce il ritmo con cui vanno processate le istruzioni. Maggiore è la frequenza con cui viene generato il clock, più velocemente vengono processate le istruzioni. Se prendiamo due processori identici, quello con la frequenza di clock maggiore è chiaramente più veloce, tuttavia, se un processore per eseguire una moltiplicazione deve iterare migliaia di somme, per quanto la sua frequenza di clock sia elevata non potrà mai competere con uno capace di eseguirle via hardware. E' il motivo per cui le macchine di Turing hanno un interesse puramente teorico e non vengono usate come modello per i computer reali. Soprattutto negli anni passati, tra Intel e AMD si instaurò una competizione serrata basata sulla frequenza di clock, come se essa fosse l'unico parametro per giudicare la velocità di un processore. Forse uno dei motivi di questo approccio va ricercato nell'ignoranza dei consumatori, abituati a giudicare un processore (e addirittura un intero computer!) unicamente in base a questo parametro: nacque mito dei MHz. Intel arrivò a produrre CPU Pentium 4 che lavoravano a frequenza superiori ai 3 GHz, frequenze di molto superiori anche a quelle dei processori attuali. All'epoca possedevo un computer con processore della AMD: il suo dissipatore era grande come il pistone di una moto e corredato di due ventole. Non mancavano gli impianti di raffreddamento a liquido. Ad un certo punto entrambe le società fecero un passo indietro, probabilmente perché i portatili stavano sostituendo gradualmente i desktop e consumi e dissipazione di calore erano diventati caratteristiche di fondamentale importanza. Le attuali CPU Intel, molto superiori da tutti i punti di vista rispetto a quelle del passato, non derivano dai Pentium 4 bensì dai Pentium M, processori per portatili derivati a loro volta dai Pentium 3. I Pentium 4 hanno terminato la loro corsa in un vicolo cieco. Fu solo in seguito alla produzione dei processori Core (operanti a frequanze minori ma più ottimizzati e dotati di parallelismo reale) che anche Apple decise di passare a processori Intel (prima utilizzava processori PowerPC). Da queste considerazioni risulta evidente che la frequenza non è un buon parametro per misurare la velocità di un processore. In genere per questo scopo si usano dei programmi dedicati chiamati benchmark, anche se solo l'esecuzione del programma reale che ci interessa utilizzare può dirci davvero quanto quel processore è adatto per i nostri scopi. Finora si è parlato solo della frequenza del processore, ma tutte le altre componenti del computer hanno una propria frequenza di lavoro. In passato la memoria centrale operava alla stessa frequenza delle CPU ma col tempo i processori hanno adottato frequenze molto più elevate (anche se il gap massimo è stato raggiunto anni fa, all'epoca dei Pentium 4, mentre ora si sono riavvicinate). Dispositivi di input/output I dispositivi di input/output servono a scambiare dati con l'esterno. I dispositivi di input li ricevono, quelli di output li inviano, quelli di input/output entrambe le cose. Alcuni dispositivi servono ad interfacciare i computer con gli esseri umani, altri ad interfacciare i computer con altri computer, altri ancora a memorizzare dati in modo permanente, magari per essere trasferiti su altri computer in un secondo tempo. Al tempo di Von Neumann non esisteva nessuno dei moderni dispositivi di input/output e quelli esistenti servivano principalmente ad interfacciare la macchina con gli esseri umani. Alcuni esempi di dispositivi odierni piuttosto comuni: • Da umano a computer (input): Tastiera, mouse, gamepad, scanner, microfono; • Da computer ad umano (output): Monitor, stampante, casse acustiche; • Da computer ad umano e viceversa (input/output): Touch screen, stampante multifunzione; • Da computer a computer e viceversa (input/output): scheda di rete; • Da memoria di massa a computer (input): lettore CD e DVD; • Da computer a memoria di massa e viceversa (input/output): masterizzatore CD e DVD, hard disk (sia rimovibile che interno), chiavetta USB, registratore di nastri magnetici. Esempi di Dispositivi di I/O A differenza della memoria centrale e del processore, nessun dispositivo di I/O è fondamentale per il funzionamento del computer. In alcuni dispositivi le tastiere vengono sostituite da touch-screen, gli hard disk da unità allo stato solido. Le casse acustiche sono comode ma se ne potrebbe fare a meno (nei computer dei laboratori per evitare confusione non ci sono). Fino a non molti anni fa le schede per reti cablate erano presenti di rado mentre nei computer moderni sono state affiancate e in certi casi addirittura sostituite da dispositivi wireless. Nei computer degli anni ottanta (primi anni novanta) gli hard disk spesso non erano presenti (i miei primi computer utilizzavano musicassette come memorie di massa). Normalmente i siti web vengono ospitati da computer dotati solo di scheda di rete, privi di monitor, mouse e tastiera. I dispositivi di I/O sono molti e cambiano nel tempo. Nessuno può dirsi indispensabile ma chiaramente ne serve almeno uno di input ed uno di output (o uno di input/output). In caso contrario il computer non potrebbe comunicare con l'esterno. Tra i dispositivi di I/O una menzione particolare spetta all'hard disk. Come ogni altro dispositivo di I/O non è fondamentale però per almeno un ventennio ha ricoperto un ruolo di primo piano sia nei computer fissi che nei portatili. Poco prima della sua diffusione molti computer erano dotati solo di unità per floppy disk o anche solo di lettori per nastri (spesso musicassette). Attualmente il ruolo dell'hard disk è messo in discussione dalle unità allo stato solido, per ora limitate ad alcuni portatili, ma in futuro probabilmente presenti in ogni computer. Gli ssd (solid state drive) offrono maggiore affidabilità (non tutti), tempi di accesso molto più bassi e costanti (come conseguenza sono indifferenti alla frammentazione), scaldano e consumano meno. Attualmente hanno ancora un costo al byte molto maggiore ma le cose stanno cambiando piuttosto velocemente. Su questa Disco rigido pagina di Wikipedia si trova una descrizione molto dettagliata di questo dispositivo di I/O. Aggiungo solo alcune precisazioni dopo una descrizione veloce del dispositivo. Un hard disk è formato da uno o più piatti ricoperti di materiale magnetico. Sulle ogni faccia dei piatti è presente una testina di lettura e scrittura. I piatti ruotano molto velocemente, con velocità angolare costante (dipendente dal modello di hard disk). La superficie di un piatto è ovviamente continua. Per essere utilizzata va resa discreta tramite un procedimento chiamato formattazione a basso livello da non confondere assolutamente con la formattazione classica, che riguarda il file-system: a questo livello il file-system è come se non esistesse. La formattazione a basso livello viene effettuata dal produttore dell'hard disk, tuttavia è possibile effettuarla anche da soli con particolari programmi messi a disposizione dal produttore che cambiano a seconda del modello del dispositivo. Formattare un hard disk a basso livello è un po' come piastrellare un pavimento: una superficie prima continua viene suddivisa in un numero finito di parti, dette settori, generalmente di 512 byte, disposti su un numero finito di tracce concentriche. Tracce equidistanti dal centro formano un cilindro. Nei primi hard disk ogni traccia aveva lo stesso numero di settori e questa è la descrizione classica che tutt'ora viene riportata su molti libri e siti. In realtà è da molto tempo che i dischi vengono formattati diversamente. Infatti, se ogni traccia avesse lo stesso numero di settori, la densità dei dati nelle tracce esterne sarebbe molto più bassa, con conseguente spreco di spazio. Si preferisce allora suddividere i piatti in regioni: quelle esterne hanno tracce con più settori di quelle interne e quindi, se la testina si trova all'esterno, in un giro scorre su un numero maggiore di byte. Essendo la velocità angolare del disco costante, nelle regioni esterne gli accessi (letture e scritture) sono più veloci che nelle regioni interne. La differenza di prestazioni, su alcuni dischi, è stata misurata e può arrivare al 30% (ma ovviamente dipende da moltissimi fattori). Anche per questo motivo vengono riempite sempre prima le regioni esterne. Bus Nel secondo modello ideato da Von Neumann, quello a cui generalmente, anche se non del tutto correttamente ci si riferisce con l'appellativo di “Architettura di Von Neumann” i bus sono dei canali di comunicazione che collegano processore, memoria centrale e dispositivi di I/O. Per semplificare, in seguito eviterò di menzionare i dispositivi di I/O in quanto nei computer reali esistono tre approcci differenti per accedervi e sono argomenti che esulano dalle finalità di questo testo. In origine probabilmente i bus erano dei veri e propri fili, poi sono stati realizzati tramite delle piste in rame sulla scheda madre (concettualmente non vi è nessuna differenza). Nei computer reali moderni la struttura dei bus è un po' differente e piuttosto complicata ma a noi interessano i concetti di base, ed in questo senso l'idea di Von Neumann è ancora attuale. Vi sono tre tipi di bus: • Bus dati: Serve a trasportare dati dalla memoria al processore e viceversa. In altre parole questo bus dice COSA viene letto o scritto. • Bus indirizzi: Serve a selezionare la locazione di memoria in cui si devono effettuare le operazioni di lettura e scrittura. In altre parole dice DOVE leggere o scrivere. • Bus di controllo: Serve ad indicare se va effettuata una operazione di lettura, una operazione di scrittura o nessuna delle due. In altre parole dice SE leggere, scrivere o non effettuare nessuna delle due operazioni. Ricopre anche altre altre funzioni su cui per ora non abbiamo interesse a soffermarci. Esistono architetture con processori operanti su numeri interi di 8 bit con bus dati di 8 bit e bus indirizzi di 16 (gli home computer degli anni '80 erano quasi tutti così), altre operanti su interi di 16 bit con bus dati di 16 bit e bus indirizzi di 20 bit (i primi pc dell'IBM, da cui gli attuali pc derivano , dotati di processore 8086), altre che operano su interi di 32 bit dotate di bus dati e indirizzi di 32 bit (dall'80386 in poi) o di soli 16 bit (il Motorola 68000 utilizzato sia dall'Amiga che dall'Atari ST), altre con interi e un solo bus, sia per i dati che per gli indirizzi (!!!) a 64 bit (le Silicon Graphics con processore R4000). Da notare che la prima architettura a 64 bit fu realizzata dalla Silicon Graphics per le sue workstation grafiche nel 1991 (!!!!). Indirizzamento La larghezza del bus indirizzi, ossia al numero di “fili” di cui si compone il bus, determina il numero di indirizzi che si possono scrivere. Poiché ogni “filo” può assumere due valori (tensione bassa o tensione alta, 0 o 1), il numero di combinazioni possibili è 2n, dove n è il numero di “fili”. Per esempio, con 1 “filo” abbiamo 2 (21) sole combinazioni: 0 e 1. Con 2 ne abbiamo 4 (22): 00, 01, 10, 11 Con 3 ne abbiamo 8 (23): 000, 001, 010, 011, 100, 101, 110, 111. Con 4 ne abbiamo 16 (24): 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111. … Con 8 ne abbiamo 256 (28): da 00000000 a 11111111. … Con 16 ne abbiamo 65536 (216): da 00000000 a 11111111. … Con 32 ne abbiamo 4294967296 (232): da 0000000000000000 a 1111111111111111. … Con 64 ne abbiamo 18446744073709551616 (2 64): da 00000000000000000000000000000000 a 11111111111111111111111111111111 . ... Poiché i “fili” del bus indirizzi sono un numero finito ed invariabile (dipendente dall'architettura), risulta chiaro che la quantità massima di indirizzi (e quindi di memoria indirizzabile) è finita (notare che, al contrario, le memorie ad accesso sequenziale non hanno una capacità massima prefissata) ed è sempre una potenza di due. I banchi di RAM in commercio sono anch'essi sempre potenze di due, MAI potenze di dieci (se sulla scheda madre si possono inserire più banchi non è detto però che la memoria totale sia una potenza di due). Accade tuttavia che quando si fa riferimento a grossi quantitativi di memoria si approssimi la loro capacità alla potenza di dieci più vicina. Per esempio, quando si parla di un kB di RAM in genere ci si riferisce a 1.024 byte, quando si parla un MB a 1.048.576 byte, quando si parla di un GB a 1.073.741.824 byte. Molti programmi e molti libri di testo adottano questa errata convenzione. Per ovviare al problema il SI ha ideato i prefissi per multipli binari: kibi (ki), mebi (Mi), gibi (Gi), tebi (Ti). ki=210~103=k Mi=220~106=M Gi=230~109=G Ti=240~1012=T … (~ significa all'incirca uguale a) Apro una piccola parentesi (del tutto opzionale). Talvolta si afferma che i computer siano implementazioni della macchina di Turing universale. Ovviamente i computer reali non possono disporre di una memoria infinita, a differenza delle macchine di Turing, che sono astrazioni matematiche. Tuttavia, anche ipotizzando di aggiungere memoria, qualora quella presente non fosse sufficiente alla risoluzione di un certo problema (per esempio il calcolo del fattoriale di un numero), la quantità massima di memoria centrale utilizzabile è comunque limitata dalla larghezza del bus indirizzi. L'unico modo per bypassare questo limite consisterebbe nell'utilizzo di una memoria di massa ad accesso sequenziale, per esempio un nastro (cartaceo o magnetico). Numeri e sistemi di numerazione Sulla definizione di numero molti insigni matematici si sono rotti la testa ed altri altrettanto insigni l'hanno persa. Non è chiaramente il fine di questo testo darne una definizione rigorosa. Mi preme sottolineare una cosa fondamentale: è importante non confondere un numero con il simbolo utilizzato per rappresentarlo. Per esempio, vi sono diversi modi per rappresentare il numero dodici: • dodici lingua italiana; • IIIIIIIIIIII stecchini dei primitivi/tacche dei nemici uccisi sul calcio della pistola; • 12 notazione posizionale decimale; • XII numero romano; • 1100 notazione posizionale binaria. Sono tutti modi di rappresentare lo stesso numero, appartenenti a culture ed ambiti differenti. Tra loro però ce ne sono alcuni più adatti di altri • A scrivere un numero; • Ad ordinare due numeri; • Ad effettuare operazioni aritmetiche su due numeri. Il sistema di numerazione migliore è senza dubbio quello posizionale, ideato in India e diffuso in occidente dagli arabi. In questo sistema di numerazione ogni cifra, in base alla sua posizione, ha un differente peso. Nel sistema posizionale decimale vengono usate dieci cifre {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} e per questo viene detto anche a base dieci. La prima cifra a partire da destra (gli arabi scrivono da destra a sinistra) indica quante unità, la seconda quante decine, la terza quante centinaia, … compongono il numero. Usando un sistema posizionale è possibile, tramite algoritmi che si basano solo sui simboli (cioè sul modo in cui sono scritti i numeri) : • Rappresentare qualunque numero naturale (addirittura qualunque razionale, con qualche accorgimento, ma comunque per ora ci interessano solo i naturali). E' una operazione meno banale di quanto sembri: i romani, per esempio, non credo potessero scrivere un numero naturale arbitrariamente grande. • Confrontare due numeri qualsiasi e dire qual'è il maggiore. Confrontare due numeri a e b significa confrontare i due insiemi aventi rispettivamente a e b elementi e vedere quale insieme ha più elementi. Potrebbe essere un procedimento molto lungo, se i numeri sono “grandi”, anche solo dell'ordine delle centinaia. Immaginatevi intenti ad ad associare centinaia di elementi per vedere quale dei due insiemi ne contiene di più! Al contrario, se rappresentiamo i numeri con la notazione posizionale, tutto si riduce ad un confronto tra i simboli che rappresentano i due numeri. Il numero che ha più cifre è il maggiore (e con sole tre cifre si possono rappresentare ben mille numeri!). Se hanno lo stesso numero di cifre, partendo da quelle di peso maggiore, si controlla fino a che non se ne trovano due diverse: il numero con la cifra maggiore è il maggiore. Se le cifre sono tutte uguali chiaramente i numeri sono uguali. Banale e molto veloce. • Addizionare due numeri. Addizionare a e b significa contare il numero di elementi dell'insieme derivante dall'unione di due insiemi disgiunti aventi rispettivamente a e b elementi. Detto in parole povere, 3+2 significa prendere due sacchetti, uno con 3, l'altro con 2 biglie, mettere tutte le biglie in un unico sacchetto e contarle. I romani al posto delle biglie usavano i sassolini (calcolare deriva da calculus che in latino vuol dire sassolino) e sicuramente anche qualche accorgimento extra per velocizzare il calcolo, ma la sostanza era simile: poiché i simboli che usavano per rappresentare i numeri non erano molto adatti ad effettuare neppure le più semplici operazioni aritmetiche, dovevano arrangiarsi come potevano. L'algoritmo della somma che ci è stato insegnato, invece, è estremamente efficiente in quanto sfrutta il modo in cui sono scritti i numeri, cioè i simboli, trascurando il significato reale dell'operazione. Per questo sommare due numeri anche molto grandi (dell'ordine delle migliaia) per noi è un gioco da ragazzi. Attenzione però! Il cosiddetto “algoritmo della somma tra numeri naturali” che ci è stato insegnato fin dalle elementari, andrebbe più propriamente chiamato “algoritmo della somma tra numeri naturali scritti in notazione posizionale decimale” perché funziona solo se i numeri sono scritti in questa notazione (e come abbiamo visto i numeri si possono scrivere in molti modi diversi...). Il vero algoritmo della somma invece, quello che unisce i sacchettini di biglie, per intenderci, funziona in ogni caso, indipendentemente dal modo in cui sono scritti i numeri. Chiaramente non esiste solo il solo sistema posizionale decimale. Dato che le basi sono infinite (base 2, base 3, base 4, …} possiamo inventarci quanti sistemi posizionali vogliamo ed usare quello che più ci aggrada. Tra le infinite possibili, la base 2 ha avuto particolare successo nell'informatica per la sua estrema semplicità. Se a qualcuno la base 10 appare più semplice è solo per abitudine. Pensate per esempio alle regole apprese da bambini per sommare due numeri in base 10: 0+0=0 0+1=1 0+2=2 0+3=3 …, 1+0=1 1+1=2 1+2=3 1+3=4 … 2+0=2 2+1=3 2+2=4 2+3=5 … In tutto sono 100! Le regole per sommare numeri in base 2 invece sono solo 4: 0+0=0 0+1=1 1+0=1 1+1=0 con riporto di 1 Semplice vero? Semplice anche per la ALU che deve svolgere in continuazione questi compiti!. I numeri scritti in binario hanno però lo svantaggio di essere molto lunghi. Per il computer non è un problema, per gli uomini purtroppo sì. Cambiamenti di base Se un calcolatore adotta il sistema di numerazione binario, gli input vanno inseriti in base 2 e gli output vengono forniti anch'essi in questa base. Presumendo che gli utilizzatori siano degli esseri umani, si rendono pertanto necessarie due conversione: dalla base 10 alla base 2 per gli input, dalla base 2 alla base 10 per gli output. Queste conversioni si potrebbero effettuare a mano, ma sarebbe un compito ingrato. In alternativa si potrebbero affidare alla macchina. Per i moderni computer, che adottano il sistema di numerazione binario, ovviamente esistono già programmi che implementano gli algoritmi di conversione. Le prime calcolatrici meccaniche, la macchina analitica di Babbage, persino il relativamente recente Eniac adottavano invece un sistema di numerazione decimale proprio per evitare di dover convertire gli input e gli output. Tuttavia questo approccio, se da un lato evita le conversioni, dall'altro complica notevolmente l'hardware. Anche se esistono programmi apposta per passare da una base all'altra e nell'uso quotidiano del computer queste conversioni vengono fatte automaticamente, tuttavia è utile imparare come funzionano e soprattutto capire perché. Bisogna per prima cosa imparare a scrivere i numeri come i primitivi (non so se effettivamente i primitivi scrivessero i numeri così ma mi piace pensarlo). Ecco alcuni esempi: 0 (assenza di stecchini) 1 I (uno stecchino) 2 II (due stecchini) 3 III (tre stecchini) … Mi piace usare gli stecchini perché sono molto vicini all'essenza stessa del numero. Avrei potuto usare biglie, sassolini, cammelli, bisonti … ma gli stecchini sono più facili da disegnare. Prendiamo ad esempio il numero decimale 27. Significa: 7 da I 2 da IIIIIIIIII Ossia: I I I I I I I IIIIIIIIII IIIIIIIIII (ho lasciato volutamente gli spazi) Un procedimento analogo va applicato con la base due. Se vogliamo sapere che numero è 10011: 1 da I 1 da II 0 da IIII 0 da IIIIIIII 1 da IIIIIIIIIIIIIIII Ossia I II IIIIIIIIIIIIIIII (ho lasciato volutamente gli spazi) Il bello della base due è che l'ennesimo gruppetto di stecchini o c'è o non c'è. Questo procedimento ci permette di passare da una qualunque notazione posizionale agli stecchini (cioè all'essenza del numero). Il procedimento inverso, un po' più complicato ma non troppo, ci permette di passare dagli stecchini ad una qualunque notazione posizionale. Per esempio, proviamo ad esprimere il numero del primo esempio, IIIIIIIIIIIIIIIIIIIIIIIIIII (ho tolto volutamente gli spazi) che in decimale si scriveva 27 in forma binaria. Potrei avere molti gruppi da I IIIIIIIIIIIIIIIIIIIIIIIIIII Ma potrei fare anche meglio: 1 gruppo da I e molti gruppi da II I II II II II II II II II II II II II II Meglio: 1 gruppo da I, 1 gruppo da II e molti gruppi da IIII I II IIII IIII IIII IIII IIII IIII II I Ancora meglio: 1 gruppo da I, 1 gruppo da II , 0 gruppi da IIII e molti gruppi da IIIIIIII I II IIIIIIII IIIIIIII IIIIIIII Ci siamo quasi: 1 gruppo da I, 1 da II, 0 da IIII, 1 da IIIIIIII, e molti da IIIIIIIIIIIIIIII I II IIIIIIII IIIIIIIIIIIIIIII La risposta definitiva è: 1 gruppo da I, 1 da II, 0 da IIII, 1 da IIIIIIII, 1 da IIIIIIIIIIIIIIII I II IIIIIIII IIIIIIIIIIIIIIII che alla araba (da destra a sinistra) si scrive 11011 Ora proviamo a tradurre il numero IIIIIIIIIIIIIIIIIII, che in binario si scriveva 10011 in notazione decimale. Molti gruppi da I IIIIIIIIIIIIIIIIIII 9 gruppi da 1 e molti gruppi da IIIIIIIIII I I I I I I I I I IIIIIIIIII 9 gruppi da 1 e 1 gruppo da IIIIIIIIII I I I I I I I I I IIIIIIIIII Che alla araba si scrive 19. Notare che, per passare dalla notazione posizionale agli stecchini si effettuano delle moltiplicazioni (ogni cifra di un numero scritto in notazione posizionale indica quante volte prendere un gruppo di stecchini, quindi è una moltiplicazione) e poi si sommano i risultati (si uniscono gli stecchini). Al contrario, per passare dagli stecchini alla notazione posizionale, si effettuano delle divisioni successive (facendo i gruppi) e si tengono i resti. Una volta che si è capito il procedimento, siccome siamo abituati a scrivere i numeri e ad eseguire i calcoli in base dieci, se vogliamo convertire i numeri da e per questa base, possiamo sostituire gli stecchini coi numeri in notazione posizionale decimale. A questo punto è lecito chiedersi se sia necessario passare sempre dagli stecchini per convertire un numero da una base a un'altra. La risposta è ovviamente no anche se gli stecchini (o le pedine) sono il metodo migliore per capire perché e come funziona l'algoritmo. Prendiamo per esempio il numero 19 (base 10) e proviamo a convertirlo in base 2 senza passare dagli stecchini. Abbiamo due modi per farlo. Il primo consiste nel sostituire agli stecchini la base 10. Il procedimento adottato per passare dagli stecchini alla base desiderata è quello di formare i gruppi (e poi gruppi di gruppi e così via) e tenere gli avanzi troppo piccoli per essere raggruppati, ossia nell'eseguire delle divisioni successive tra interi tenendo i resti. Per scrivere il numero decimale 19 in base due basta dividerlo per due, dividere il risultato per due e così via fino ad ottenere 0 (e quindi non poterlo più dividere) tenendo i resti: 19/2=9 con resto di 1 9/2=4 con resto di 1 4/2=2 con resto di 0 2/2=1 con resto di 0 1/2=0 con resto di 1 I resti, partendo dall'ultimo, sono 10011 che è il numero cercato. Il secondo metodo è quello di sostituire gli stecchini con la base 2. Il numero 19 significa una decina e nove unità: tradotto in binario 1 (uno) da 1010 (dieci) 1001 (nove) da 1 (uno) 1*1010+1001*1=10011. Questo secondo metodo, sebbene possa apparire più veloce, ha un difetto: per applicarlo devo già sapere come scrivere in binario tutti i numeri compresi tra zero e dieci (nel caso specifico mi basta sapere come si scrivono uno, nove e ovviamente dieci). Proviamo ora a fare il contrario, ossia a convertire il numero binario 10011 in base dieci senza passare per gli stecchini. Assumiamo che il numero in binario prenda il posto degli stecchini: dobbiamo eseguire le solite divisioni tenendo il resto. Con gli stecchini avrei fatto dei gruppi da dieci, poi da dieci decine e così via, quindi devo dividere il numero per dieci, il risultato ancora per dieci etc. Attenzione però: il numero è scritto in binario e quindi anche il divisore (dieci) va scritto in questa base (l'algoritmo comunque è lo stesso). 10011:1010 (dieci) =1 con resto di 1001 che in decimale corrisponde a 9 1:1010=0 con resto di 1010 che in decimale corrisponde a 1 Per funzionare funziona, tuttavia dobbiamo già sapere come si scrivono in binario tutti i numeri da zero a dieci (nel caso specifico uno, nove ed ovviamente dieci). Se invece adotto il secondo metodo, ossia assumo che sia il decimale a prendere il posto degli stecchini, il procedimento è il seguente: 10011 significa: 1 da 1 (20) 1 da 2 (21) 0 da 4 (22) 0 da 8 (23) 1 da 16 (24) ossia 1*1+1*2+0*4+0*8+1*16=19 A questo punto viene spontaneo chiedersi quale dei due metodi convenga adottare per effettuare una conversione da una base all'altra. La risposta è: se la base di partenza è maggiore conviene eseguire le divisioni successive (perché i resti saranno sempre cifre presenti in entrambe le basi), se invece la base di partenza è minore conviene sommare tra loro le cifre del numero moltiplicate per il corrispettivo peso (perché le cifre che compongono il numero saranno sempre presenti in entrambe le basi). Insiemi numerici Le memorie dei computer contengono un numero finito di bit. Gli insiemi numerici dei naturali (N), degli interi (Z) e dei razionali (Q) invece sono infiniti. L'insieme dei reali (R) è infinito e addirittura più numeroso di quello dei tre precedenti. Quello a fianco è un diagramma di Venn tratto da Wikipedia relativo agli insiemi numerici. Da notare che il fatto che un insieme numerico ne contenga un altro non implica necessariamente che sia più numeroso (potrebbe avere lo stesso numero di elementi). Simili apparenti paradossi sono comuni quando si tratta con insiemi infiniti. In base a quanto riportato, risulta evidente che i computer hanno e avranno sempre grossi problemi coi numeri in quanto i numeri sono infiniti (addirittura i reali sono più che numerabili...) le memorie no. I computer possono rappresentare solo un sottoinsieme finito dei razionali (e quindi anche degli interi): per tutti gli altri numeri si rendono necessari degli arrotondamenti. Riguardo ai reali non razionali, nessun computer è in grado di rappresentarli nativamente perché non sono rappresentabili in notazione posizionale con un numero finito di cifre e neppure con un periodo che si ripete. Addirittura, per la stragrande maggioranza dei reali, non esiste un algoritmo (una procedura meccanica) in grado di rappresentarli, ma questa è un'altra storia...