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...