Il 0% ha trovato utile questo documento (0 voti)
24 visualizzazioni225 pagine

AdE Semplice (Per Davvero)

Caricato da

colettilorenzo05
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
24 visualizzazioni225 pagine

AdE Semplice (Per Davvero)

Caricato da

colettilorenzo05
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 225

Architettura

degli elaboratori
semplice (per
davvero)

Rovesti Gabriel
Architettura degli elaboratori semplice (per davvero)

Attenzione
1
Il file non ha alcuna pretesa di correttezza; di fatto, è una riscrittura attenta di appunti, slide, materiale sparso in rete,
approfondimenti personali dettagliati al meglio delle mie capacità. Credo comunque che, per scopo didattico e di piacere di
imparare (sì, io studio per quello e non solo per l’esame) questo file possa essere utile. Semplice si pone, per davvero ci
prova.
Thank me sometimes, it won’t kill you that much.

Gabriel

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

2
Sommario
Introduzione ................................................................................................................................................................................................ 3
Evoluzione dei calcolatori ........................................................................................................................................................................... 5
Notazione binaria, ottale, esadecimale. Algebra di Boole .......................................................................................................................... 8
Componenti e connessioni ........................................................................................................................................................................ 11
Bus ............................................................................................................................................................................................................. 17
QuickPath Interconnect (QPI) ................................................................................................................................................................... 19
Gerarchie di memoria ............................................................................................................................................................................... 21
Memorizzazione ed organizzazione (Mapping della cache) ..................................................................................................................... 24
Esercizi cache 1 ......................................................................................................................................................................................... 32
Memorie interne ....................................................................................................................................................................................... 37
Read Only Memory (ROM) ........................................................................................................................................................................ 41
Memorie esterne ...................................................................................................................................................................................... 52
Dischi magnetici .................................................................................................................................................................................... 53
Memoria magnetica di lettura e scrittura ............................................................................................................................................. 53
Organizzazione e formattazione dei dati .............................................................................................................................................. 54
Caratteristiche fisiche ........................................................................................................................................................................... 55
Dischi RAID ............................................................................................................................................................................................ 57
Dischi SSD (Solid State Drives)/Dischi a stato solido ................................................................................................................................. 70
Memorie esterne: CD-ROM ...................................................................................................................................................................... 75
Gestione I/O .............................................................................................................................................................................................. 80
Esercizi sulla prima parte .......................................................................................................................................................................... 88
Aritmetica del calcolatore ......................................................................................................................................................................... 96
Rappresentazione e Aritmetica Numeri Reali ......................................................................................................................................... 107
Esercizi su virgola mobile ........................................................................................................................................................................ 111
Linguaggio macchina ............................................................................................................................................................................... 112
Modi di indirizzamernto .......................................................................................................................................................................... 118
Struttura e funzione del processore........................................................................................................................................................ 124
Pipeline.................................................................................................................................................................................................... 130
Esercizi pipeline ....................................................................................................................................................................................... 155
Filosofia RISC ........................................................................................................................................................................................... 158
CISC ......................................................................................................................................................................................................... 165
Architettura MIPS-32 .............................................................................................................................................................................. 167
Processori multicore ............................................................................................................................................................................... 197
Esercizi pipeline parte 2 .......................................................................................................................................................................... 201
Contenuti integrativi: Circuiti e Microprogrammazione ......................................................................................................................... 219
Altri esercizi pipeline ............................................................................................................................................................................... 223

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Introduzione 3

Architettura: caratteristiche visibili al programmatore


- Istruzioni
- Spazi (numero bit) usato per rappresentare i dati
- Tecniche di indirizzamento della memoria
Organizzazione: unità operative e loro connessioni
- Interfacce tra calcolatore e periferiche
- Tecnologia per le memorie
Esempio: Istruzione per la moltiplicazione:
- Decidere se è disponibile, è una decisione architetturale
- Come implementarla (circuito per la moltiplicazione o somme ripetute) è una decisione di
organizzazione (costo, velocità, ...)
Modelli diversi della stessa marca: stessa architettura, organizzazione diversa
- Esempio: architettura dell’IBM 370 (dal 1970)
o Fino ad oggi per calcolatori mainframe
o Varie organizzazioni con costo e prestazioni diverse

Struttura e funzione
Calcolatore:
- Insieme di componenti connesse tra loro
Visione gerarchica
- Insieme di sottosistemi correlati
- Ogni sistema ad un livello si basa sulla descrizione astratta del
livello successivo
Ad ogni livello
- Struttura: come sono correlati i componenti
- Funzione: cosa fa ciascun componente
Descrizione top-down:
- da componenti principali a sottocomponenti, fino a una
descrizione completa dei dettagli

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Funzioni basilari di un calcolatore (livello più alto della gerarchia) 4


- Elaborazione dati
- Memorizzazione dati
- Trasmissione dati
o Input/output o verso un dispositivo remoto
- Controllo
o Delle tre funzioni sopra

Struttura (livello più alto della gerarchia)


Quattro componenti principali:
- Unità centrale di elaborazione (CPU)
o Esegue le funzioni di
elaborazione dati
- Memoria centrale
o Per immagazzinare i dati
- I/O (input/output)
o Per trasferire i dati tra
calcolatore ed esterno
- Interconnessioni
o Per far comunicare CPU,
memoria centrale, e I/O

Central Processing Unit (Unità Centrale di


Elaborazione)
- Unità di controllo
o Controlla la sequenza di
operazioni
- Unità aritmetico-logica (ALU)
o Elaborazione dati
- Registri
o Memoria interna della CPU
- Interconnessioni
o Comunicazione tra unità di
controllo, ALU e registri

Dentro la CPU vediamo l’unità di controllo, è un componente della CPU ( Central Processing Unit ) di un
computer. L'unità di controllo è conosciuta anche con la sigla CU ( Control Unit ). È il dispositivo della CPU a
cui spettano le funzioni di controllo. L'unità di controllo coordina il flusso di dati tra il processore e gli altri
componenti del computer, legge ed esegue le istruzioni nella memoria centrale. Il funzionamento dell'unità
di controllo del computer si basa sul processo fetch-execute ( lettura-esecuzione ).
- Fetch. Nella fase fetch ( lettura ) l'unità di controllo legge dalla memoria centrale del computer le
istruzioni da eseguire, scrivendole nel registro di istruzione. Le istruzioni sono registrate in
particolari locazioni di memoria consecutive, al fine di agevolare la successiva operazione di
interpretazione ed esecuzione sequenziale delle istruzioni mediante la locazione del contatore di
programma ( program counter ).
- Execute. Nella fase execute ( esecuzione ) l'unità di controllo interpreta ed esegue in modo
sequenziale le istruzioni situate nel registro di istruzione. Nel caso di calcoli tra dati numerici, l'unità
di controllo trasferisce i dati dalla memoria centrale del computer all'unità aritmetico-logica ( ALU )
e attende il risultato.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

5
L'unità di controllo legge le
istruzioni da eseguire dalla
memoria centrale e le scrive nel
registro di istruzioni, al fine di
poterle interpretare ed eseguire
in modo sequenziale, inviando
segnali di controllo alle unità del
computer interessate.

Perché studiare l’architettura dei calcolatori?


- Capire i compromessi costo-prestazioni
o Esempio: scegliere il calcolatore migliore a parità di costo
▪ spesa maggiore ma memoria più grande o frequenza di clock più alta e quindi
maggiore velocità
- Supporto ai linguaggi di programmazione
o Diverso a seconda delle architetture

Evoluzione dei calcolatori


Nel corso del tempo, l’evoluzione dei calcolatori ha portato:
- Processori sempre più veloci
- Componenti sempre più piccoli → più vicini → elaborazione più veloce
o Ma la velocità è derivata anche da nuove tecniche (pipeline, parallelismo, ecc.) che tengono
occupato il processore il più possibile
- Memoria sempre più grande
- Capacità e velocità di I/O sempre maggiore
- Tecniche per bilanciare velocità diverse di processore e memoria
o Memoria cache, ecc.
Questi, infatti, si sono adattati ad eseguire compiti ripetitivi e complessi e quindi automatizzabili. Ciò che a
noi interessa in questa lezione è il modello della macchina di Von Neumann.
- Programma memorizzabile come i dati
- Istruzioni in memoria: decidere il programma specificando una porzione di memoria
- Idea di John von Neumann (consulente ENIAC, uno dei primi calcolatori)

La struttura di Von Neumann è così formata:


- Memoria, contiene dati e istruzioni
- Molte operazioni di aritmetica, quindi
dispositivi specializzati per eseguirle è
unità aritmetico-logica (dati binari)
- Organo centrale per il controllo della
sequenza delle operazioni, generico è
unità di controllo
- Organi di ingresso e uscita

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

La struttura di Von Neumann è nota anche come 6


computer IAS.
- Memoria:
o 1000 locazioni (parole), numerate
da 0 a 999 (indirizzo)
o Ogni parola: 40 cifre binarie (0 o 1,
bit)
- Dati e istruzioni in memoria:
o numeri in forma binaria: bit di segno
+ 39 bit per il numero
o istruzioni con codice binario:
▪ due in ogni parola
▪ 8 bit per codice istruzione,
12 bit per indirizzo parola di
memoria
- Unità di controllo: preleva le istruzioni dalla
memoria e le esegue una alla volta
La struttura è quella riportata a lato.

I registri IAS invece sono:


- MBR (memory buffer register)
o Contiene una parola da immagazzinare in memoria, o da leggere dalla memoria
- MAR (memory address register)
o Contiene un indirizzo di una parola di memoria (dove scrivere il contenuto di MBR o da
trasferire in MBR)
- IR (instruction register)
o Contiene 8 bit per il codice operativo dell’istruzione in corso
- IBR (instruction buffer register)
o Contiene temporaneamente l’istruzione destra di una parola
- PC (program counter)
o Indirizzo della prossima coppia di istruzioni da prendere dalla memoria
- AC (accumulator) e MQ (multiplier quotient)
o Temporaneamente, operandi e risultati parziali delle operazioni della ALU

La CPU esegue un programma


memorizzato in memoria prendendo ad
una ad una le istruzioni, nell’ordine in cui
sono memorizzate. Il ciclo della CPU è
composto da (definito anche sopra nelle
due fasi):
- Prelievo dell’istruzione (fetch):
o Istruzione letta da IBR o
dalla memoria tramite
MBR, IBR, IR e MAR
o Carica il codice
dell’istruzione successiva
nell’IR e indirizzo in MAR
- Esecuzione dell’istruzione:
o Attiva i circuiti necessari
per l’operazione da
eseguire

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Le istruzioni IAS sono 21 in totale, comprendendo trasferimento dati tra i registri, salti con o senza 7
condizione tra i vari pezzi (approfondito il concetto di salto successivamente), aritmetiche, modifica di
indirizzo (da mettere in memoria). I primi 8 bit sono uno dei 21 codici e i successivi 12 sono le celle di
memoria coinvolte.
Esempi di istruzioni IAS:

La grande innovazione fu certamente l’invenzione dei transistor.


Il transistor è un dispositivo elettronico a tre terminali che amplifica o commuta segnali elettronici. I suoi
componenti essenziali sono due materiali semiconduttori, tipicamente il silicio, con proprietà opposte, noti
come tipo p e tipo n.
Quando i due materiali vengono accostati, formano una barriera a strato di deplezione. Questo strato
agisce come un interruttore, permettendo alla corrente elettrica di passare o non passare, a seconda della
tensione applicata al terzo terminale, noto come gate.
I transistor sono presenti in quasi tutti i dispositivi elettronici e sono componenti fondamentali dei circuiti
integrati o chip. Inventati nel 1947 nei Bell Laboratories, i transistor hanno rivoluzionato l'elettronica
rendendo possibili dispositivi più piccoli, più economici e più affidabili.

Ulteriore grande invenzione: il circuito integrato.


Esso è un unico pezzo di silicio per molti componenti e le loro connessioni. Col tempo, sempre più
componenti in un circuito integrato. Altre definizioni utili:
- Porta logica
o Dispositivo che esegue una semplice funzione logica
o Esempio: se A e B sono veri allora C è vero (porta AND)
- Cella di memoria: dispositivo in grado di memorizzare un bit (due stati possibili)
- Calcolatore: numero grandissimo di porte logiche e celle di M (M=memoria)
Le sue funzioni:
- Memorizzazione dati
o celle di memoria
- Elaborazione dati
o porte logiche
- Trasferimento dati
o tra memoria e memoria, direttamente o attraverso porte logiche
- Controllo
o segnali di controllo per attivare le porte logiche o leggere/scrivere una cella di memoria

Ultima grande innovazione: dispositivi time-sharing, cioè un approccio all'uso interattivo dei computer in
cui un singolo computer viene utilizzato contemporaneamente da più utenti, ciascuno con un proprio
terminale. Similare a questa l’elaborazione batch, altro modo di interagire con un mainframe, ma associato
per tutto il tempo ad un singolo utente.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Altra definizione fondamentale in 8


informatica: la legge di Moore, termine
usato per riferirsi all'osservazione fatta
da Gordon Moore nel 1965, secondo
cui il numero di transistor in un circuito
integrato (IC) denso raddoppia ogni
due anni circa.
La Legge di Moore non è morta, è
ancora valida. Sebbene sia vero che la
densità dei chip non raddoppia più ogni
due anni (quindi la Legge di Moore non
si sta più verificando secondo la sua
definizione più rigorosa), essa continua
a fornire miglioramenti esponenziali,
anche se a un ritmo più lento.

Notazione binaria, ottale, esadecimale. Algebra di Boole


Sebbene le persone lavorino con i numeri utilizzando il sistema numerico in base 10 (decimale), altri sistemi
sono rilevanti per l'informatica, tra cui quello binario (base 2) e quello esadecimale (base 16). I computer
gestiscono i dati sotto forma di sequenze di bit (cifre binarie), che sono tutti zeri o uno. Le persone hanno
maggiore familiarità con la base 10, quindi scriviamo un software che consente di utilizzare la base 10 per
comunicare con il computer.

In base 10 ci sono dieci cifre (0-9) e ogni posto vale dieci volte il posto alla sua destra.

In binario, base 2, ci sono solo due cifre (0 e 1) e ogni posto vale due volte il posto alla sua destra.

Il pedice 2 su 11012 indica che 1101 è in base 2. I numeri sono normalmente scritti in base 10, quindi il
pedice 10 viene utilizzato solo se necessario per chiarezza.

Nella notazione in base 10, ogni valore di posto rappresenta una potenza di dieci: il posto delle unità
(100 = 1), il posto delle decine (101 = 10), il posto delle centinaia (102 = 100), il posto delle migliaia
(103 = 1000), ecc. Quindi, ad esempio:

Nella notazione in base 2 si utilizza la stessa idea, ma con potenze di due invece che di dieci. I valori dei
luoghi binari rappresentano le unità (20 = 1), i due (21 = 2), i quattro (22 = 4), gli otto (23 = 8), i sei (24 = 16),
ecc. Quindi, ad esempio:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Altro esempio (delle slide): 9

Valore di una rappresentazione binaria

Valore minimo → 010


Valore massimo → 2n – 1

Ricordiamo che si parte dal cosiddetto bit (0 oppure 1). 8 bit formano un byte.
Abbiamo poi le scale:
- Kilo (103) → 1024 B/Byte formano 1 KB (Kilobyte)
- Mega (106) → 1024 KB formano 1 MB (Megabyte)
- Giga (109) → 1024 GB formano 1 MB (Gigabyte)
- Tera (1012) → 1024 GB formano 1 TB (Terabyte)
- Peta (1015) → 1024 TB formano 1 PB (Petabyte)

Per rappresentare i numeri rappresentiamo varie notazioni, ad esempio:

- Notazione ottale (base 8)


Essa è formata da 8 simboli, rappresentando ogni gruppo di 3 cifre binarie a numeri binari. Di solito hanno
una lunghezza multipla di 3.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

10
- Notazione esadecimale (base 16)
Essa è formata da 16 simboli, rappresentando ogni gruppo di 4 cifre binarie a corrispettive traduzioni. Di
solito hanno una lunghezza multipla di 4.

Avviene quindi la manipolazione logica di bit, tramite la


cosiddetta algebra di Boole, usando apposite variabili logiche
(binarie) che possono assumere valore 0 (falso) ed 1 (vero).
Le operazioni logiche di base sono come segue:
- OR (somma)
- AND (prodotto)
- NOT (opposto)
- NAND (opposto di AND)
- XOR (1 se diversi, 0 se uguali)
- XNOR (0 se diversi, 1 se uguali)

Altre tabelle utili:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

11
Componenti e connessioni
I componenti principali sono:
- La CPU
- La memoria
- Sistemi di I/O
- Connessioni tra loro

Avendo descritto l’architettura di Von Neumann, diciamo che per eseguire un programma, possiamo
costruire i componenti logici in modo che il risultato sia quello voluto. Questo è un modo di costruire il
programma “cablato”, cioè in forma hardware, che non può essere modificato.

È un sistema non flessibile, che può eseguire


solo le operazioni predeterminate (accetta
dati e produce risultati). Con circuiti generici,
accetta dati e segnali di controllo che dicono
cosa eseguire, e produce risultati. In generale,
per ogni nuovo programma, basta dare i
giusti segnali di controllo.

Definiamo quindi un programma: esso non è altro che un


insieme di passo in cui, ad ognuno, si ha una operazione
logica o aritmetica. Per ogni operazione, si ha un diverso
insieme di segnali di controllo.
Con un hardware generico che preleva il codice delle
istruzioni e genera appositi segnali di controllo, parte la
programmazione software.
La CPU è quindi sia interprete delle istruzioni che modulo
per operazioni aritmetico-logiche.

Per la memoria principale:


- Possibilità di salti oltre che esecuzione sequenziale
- Operazioni che richiedono accesso a più dati in memoria
- Immagazzinare temporaneamente sia istruzioni che dati

Come detto, al di là delle varie componenti della CPU, i passi principali del ciclo di esecuzione sono:
- Fetch (reperimento dell’istruzione)
- Execute (esecuzione dell’istruzione)

Importante in particolare è il registro PC (Program Counter): salva l’indirizzo della cella di memoria
principale contenente la prossima istruzione. In generale preleva dalla memoria e poi si incrementa.
Esempio:
- parole di M con 16 bit
- PC contiene 300
- CPU preleva l’istruzione nella cella 300, poi 301, poi 302, ... n
Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

L’istruzione prelevata viene messa in IR (Instruction Register), poi l’operazione corrispondente viene 12
eseguita.

Operazioni di 4 tipi per la CPU


1) Processore-memoria
a. Trasferimento dati tra la CPU e la M
2) Processore-I/O
a. Trasferimento dati tra CPU e I/O
3) Elaborazione dati
a. Operazione logica o aritmetica sui dati n
4) Controllo
a. Può alterare la sequenza delle istruzioni
b. Esempio: prelievo istruzione dalla cella 149, che dice che la prossima istruzione è nella cella
182.
Altro esempio:
- Somma di cella 940 e 941 e memorizzazione del risultato nella cella 941
- Tre istruzioni
- All’inizio PC contiene 300
- Celle di M in esadecimale

Il ciclo di esecuzione è così strutturato:

1) Prelievo delle istruzioni


2) Decodifica dell’operazione
3) Calcolo dell’indirizzo dell’operando (ritorna una stringa o un vettore di dati)
4) Prelievo degli operandi e calcolo se necessario per molteplici operandi
5) Operazioni sui dati
6) Calcolo dell’indirizzo dell’operando (con molteplici risultati)
7) Memorizzazione del risultato
8) Istruzione completata e prelievo successiva istruzione

Esiste un meccanismo con cui i moduli (per esempio di I/O) possono interrompere la normale sequenza du
esecuzione e queste sono le interruzioni.
Tipiche interruzioni
- Program
o Esempio: overflow, division by zero
- Timer
o Generata da un timer interno alla CPU

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- I/O 13
o Per segnalare la fine di un’operazione di I/O
- Guasto hardware
o Esempio: mancanza di alimentazione

Le interruzioni vengono fatte per migliorare l’efficienza dell’elaborazione (vari dispositivi sono pià lenti del
processore e anche per evitare che la CPU attenda la fine di un’operazione di I/O). Qui sotto un esempio:

Trasferimento del controllo per una interruzione

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

14
Come si nota, esiste l’interrupt
handler per gestire le interruzioni,
è un blocco speciale di codice
associato a una specifica
condizione di interrupt. I gestori di
interrupt vengono avviati da
interrupt hardware, istruzioni di
interrupt software o eccezioni
software e sono utilizzati per
implementare i driver dei
dispositivi o le transizioni tra
modalità operative protette, come
le chiamate di sistema.

Ci sono due tipi di interrupt:

1) Interrupt hardware generati da dispositivi esterni alla CPU (periferiche), che hanno il compito di
comunicare il verificarsi di eventi esterni, di solito dispositivi di Input/Output. Un interrupt
hardware costringe il processore a memorizzare il suo stato di esecuzione fino all'arrivo
dell'interrupt e ad iniziare l'esecuzione della subroutine (sottoprogramma) (commutazione di
contesto) che esegue il compito richiesto dall'interrupt, terminato il quale il processore riprende
l'esecuzione delle operazioni che stava precedentemente elaborando. Nella pratica, si nota un
rallentamento del sistema ed un aumento dell'uso della CPU, che può arrivare ad essere impegnata
al 100% e per lunghi periodi.
2) Interrupt software: sono delle istruzioni assembly, tipo INT xx o SYSCALL, che possono essere
assimilate alle chiamate di sottoprogrammi, ma che sfruttano il meccanismo delle interruzioni per
passare il controllo dal programma chiamante a quello chiamato, e viceversa; vengono utilizzati per
accedere direttamente alle risorse del sistema operativo.

Uso degli interrupt

Gli interrupt vengono utilizzati principalmente quando:


- un processo tenta di eseguire un'istruzione non valida, come una divisione per zero. In questi casi
non è possibile proseguire con l'esecuzione del processo, perché genererebbe parecchi errori,
corromperebbe i dati nei registri della CPU e/o porterebbe a un crash il sistema stesso. Quindi
l'interrupt consente di informare il sistema operativo di quanto avvenuto in modo da permettere la
corretta gestione del problema.
- un processo richiede un'operazione di I/O al sistema operativo. Le CPU moderne prevedono la
possibilità di utilizzare diversi livelli di privilegi, per ragioni di sicurezza, che i processi in esecuzione
possono ricevere. Solo il sistema operativo può effettuare alcune operazioni come accedere ad
alcune aree di memoria protette o gestire le periferiche.
- un dispositivo di I/O informa la CPU che è disponibile a ricevere o fornire dati. In questo caso viene
avviata un'opportuna procedura del sistema operativo preposta ad occuparsi della relativa
periferica. Questo tipo di interrupt necessita una gestione molto attenta, infatti è possibile che due
dispositivi abbiano generato un interrupt durante l'esecuzione di un processo, ed è necessario
disporre di meccanismi che evitino conflitti e la perdita di informazioni, ad esempio decidendo
quale interrupt ha maggiore priorità e deve essere eseguito per primo e ponendo in coda il
secondo, delegando il compito al Programmable Interrupt Controller.
- il tempo massimo a disposizione per tale processo è raggiunto e lo scheduler deve riassegnare la
CPU ad un altro processo in coda.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- viene effettuato il debugging di un'applicazione. Durante la fase di sviluppo di un programma è 15


frequente la necessità di testare il funzionamento di quanto creato per scoprire e risolvere l'origine
dei malfunzionamenti. Il debugging consente di seguire l'evoluzione del programma istruzione per
istruzione, dando la possibilità di interrompere il processo in qualunque momento per verificare il
valore di ogni parametro. Per effettuare questo è necessario che il codice sorgente sia compilato in
maniera apposita, in questo caso se il programma viene eseguito sotto il controllo di un apposito
programma, il debugger, ad ogni istruzione viene eseguito un interrupt che consente di verificare
se in tale punto è richiesta l'interruzione del processo.

Ciclo di interruzione
- Aggiunto al ciclo di esecuzione
- La CPU controlla se ci sono interruzioni
pendenti
- Se no, prende la prossima istruzione
- Se sì:
o Sospende l’esecuzione del
programma corrente
o Salva il contesto (es.: indirizzo
prossima istruzione)
o Imposta il PC all’indirizzo di
inizio del programma di
gestione dell’interruzione
o Esegue il programma di gestione dell’interruzione
o Rimette il contesto al suo posto e continua il programma interrotto

Le interruzioni eliminano le attese durante le operazioni di I/O,


specie se queste sono molto lunghe. Per esempio, è
tipicamente il caso delle operazioni di scrittura WRITE, come
segue a lato:

Il completamento dell’esecuzione, graficamente, aggiungendo


anche gli interrupt diventa:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Nella gestione delle interruzioni multiple 16


L'interrupt multiplo è un evento di interrupt che può verificarsi mentre il processore sta gestendo un
interrupt precedente.

Ad esempio, se un programma riceve dati da una linea di comunicazione e stampa i risultati, è possibile che
si verifichi un interrupt di comunicazione mentre viene elaborato l'interrupt della stampante.

Modalità di gestione degli interrupt


Il processore può gestire gli interrupt in due modi

1) Disabilitazione dell'interrupt - Il processore ignora ulteriori interrupt mentre ne sta elaborando uno.
Le interruzioni rimangono in sospeso e vengono controllate dopo che il primo interrupt è stato
gestito. In questo modo gli interrupt vengono gestiti in sequenza.

2) Definire le priorità - In questo metodo gli interrupt a bassa priorità possono essere interrotti da
quelli a priorità più alta. In questo caso, l'interrupt ad alta priorità viene gestito e il processore
torna all'interrupt precedente su cui stava lavorando.

Le immagini riportano una gestione delle interruzioni multiple sequenzialmente (sx) e annidate (dx)

Qui invece un esempio reale:


- Programma utente in esecuzione
- Essa viene passata al servizio di
stampa che interrompe
- Poi si passa alla routine di
comunicazione di interruzione
- Si passa anche attraverso il disco
per gestirla

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

In merito invece alle connessioni, tutte le componenti di un calcolatore devono essere connesse e ci sono 17
tipi diversi di connessione per diversi tipi di componente.
Esse sono fondamentali:
- Nella memoria permettono di leggere/scrivere indirizzi e gestire dati, dando in output dati
- Nei moduli I/O si gestiscono dati interni ed esterni in lettura/scrittura ed indirizzi, dando nuovi dati
e segnali di interruzione
- Per la CPU vi sono dati, segnali di interruzione e istruzioni in input e in output dati, indirizzi e segnali
di controllo

Connessioni per la memoria


- Riceve e spedisce dati (scrittura e lettura)
- Riceve indirizzi (di locazioni di M)
- Riceve segnali di controllo
o Lettura Connessioni:
o Scrittura - Da M a CPU: la CPU legge un’istruzione
o un dato dalla M
Connessioni dell’ Input/Output - Da CPU a M: la CPU scrive un dato in M
- Modulo di I/O: simile ad una memoria dal - Dall’I/O alla CPU: la CPU legge i dati da
punto di vista della CPU una periferica
- Operazioni di Output - Dalla CPU all’I/O: la CPU invia dati ad
o Riceve dati dalla CPU una periferica
o Manda dati alle periferiche - Dall’I/O alla M o viceversa: accesso
- Operazioni di Input diretto alla M da parte di un dispositivo
o Riceve dati dalle periferiche di I/O
o Manda dati alla CPU
- Riceve segnali di controllo dalla CPU
- Manda segnali di controllo alle periferiche
- Riceve indirizzi dalla CPU (n.ro di porta per identificare una periferica)
- Manda segnali di interruzione

Connessioni per la CPU


- Legge istruzioni e dati
- Scrive dati (dopo l’elaborazione)
- Manda segnali di controllo alle altre unità
- Riceve segnali di interruzione

Bus
La funzione principale del BUS è quella di interconnettere due o più dispositivi, quali la CPU, la memoria
centrale e le interfacce verso dispositivi periferici (I/O, memoria di massa, etc.). Di fatto, esso collega due
unità funzionali alla volta: una trasmette e l’altra riceve. Il trasferimento avviene sotto il controllo della
CPU. Un segnale trasmesso da uno dei dispositivi collegati ad un bus è disponibile a tutti gli altri.
Solo un dispositivo alla volta può trasmettere, altrimenti i segnali si sovrappongono. Normalmente, in più
linee di comunicazione, ogni linea trasmette uno 0 o un 1 n Insieme, più linee trasmettono in parallelo
numeri binari (esempio: dato da 8 bit tramesso in parallelo da un bus a 8 bit).
Qui lo schema di interconnessione dei bus:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Esistono vari tipi di bus: 18


Bus di sistema
- Connette CPU, I/O, M
- Da 50 a qualche centinaio di linee (ampiezza del bus)
- Tre gruppi di linee
o Dati: su cui viaggiano i dati (bus dati)
o Indirizzi
o Controllo

Bus dati
- Trasporta i dati (o le istruzioni)
- L’ampiezza è importante per l’efficienza del sistema
o Se poche linee, più accessi in M per prendere un dato

Bus indirizzi
- Indica la sorgente o la destinazione dei dati
o Es.: la CPU vuole leggere un dato dalla M
- L’ampiezza determina la massima quantità di M indirizzabile

Bus di controllo
- Per controllare accesso e uso delle linee dati e indirizzi
o M write: scrittura dei dati sul bus alla locazione di M
o M read: mette sul bus i dati della locazione di M
o Richiesta bus: un modulo vuole il controllo del bus
o Bus grant: è stato concesso il controllo ad un modulo
o Interrupt request: c’è una interruzione pendente
o Clock: per sincronizzare le operazioni

Uso del bus


- Se un modulo vuole inviare dati ad un altro, deve:
o Ottenere l’uso del bus
o Trasferire i dati sul bus
- Se un modulo vuole ricevere dati da un altro modulo, deve:
o Ottenere l’uso del bus
o Trasferire una richiesta all’altro modulo sulle linee di controllo
o Attendere l’invio dei dati

Se esiste un solo bus, si può avere ritardo e congestione. Normalmente, ovviamente, si cerca di usare bus
multipli per risolvere i vari problemi.
In un'architettura a bus singolo, tutti i componenti, tra cui l'unità di elaborazione centrale, la memoria e le
periferiche, condividono un bus comune. Quando molti dispositivi hanno bisogno del bus allo stesso tempo,
si crea uno stato di conflitto chiamato contesa del bus: alcuni aspettano il bus mentre un altro ne ha il
controllo. L'attesa fa perdere tempo e rallenta il computer, come spiega Engineering 360. I bus multipli
permettono a più dispositivi di lavorare contemporaneamente, riducendo i tempi di attesa e migliorando la
velocità del computer. I miglioramenti delle prestazioni sono la ragione principale per la presenza di più bus
nel progetto di un computer.

La disponibilità di più bus offre una maggiore scelta per il collegamento dei dispositivi al computer, poiché i
produttori di hardware possono offrire lo stesso componente per più di un tipo di bus. Come sottolinea Digital
Trends, la maggior parte dei PC desktop utilizza l'interfaccia Serial Advanced Technology Attachment per le
unità disco interne, ma molte unità disco esterne e unità flash si collegano tramite USB. Se le connessioni

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

SATA del computer sono tutte utilizzate, l'interfaccia USB consente di collegare ulteriori dispositivi di 19
archiviazione.

Come per tutti i componenti di un computer, i design dei bus si evolvono, con l'introduzione di nuovi tipi ogni
pochi anni. Ad esempio, il bus PCI che supporta le schede video, di rete e altre schede di espansione è
precedente alla più recente interfaccia PCIe, mentre l'USB è stato sottoposto a diverse revisioni. La presenza
di più bus che supportano apparecchiature di epoche diverse consente di mantenere le apparecchiature
tradizionali, come le stampanti e i dischi rigidi più vecchi, e di aggiungere anche dispositivi più recenti.

Chiaramente, gli eventi sui bus vanno coordinati per mezzo della temporizzazione.
- Coordinazione degli eventi su un bus
- Sincrona
o Eventi determinati da un clock
o Una linea di clock su cui viene spedita una sequenza alternata di 0 e 1 di uguale durata
o Una singola sequenza 1-0 è un ciclo di clock
o Tutti i dispositivi connessi al bus possono leggere la linea di clock
o Tutti gli eventi partono dall’inizio di un ciclo di clock

QuickPath Interconnect (QPI)

Anche se l’architettura Core è stata straordinariamente efficiente, alcuni dettagli della progettazione hanno
iniziato a mostrare la loro età, primo fra tutti il Front Side Bus (FSB). Questo bus, che connette i processori al
Northbridge, è stato la nota dolente di un’architettura moderna. Il difetto era maggiormente visibile in
configurazione multiprocessore, dove l’architettura faticava nella gestione dei crescenti carichi di lavoro. I
processori dovevano condividere il bus, non solo per accedere alla memoria, ma anche per assicurare la
coerenza dei dati contenuti nelle rispettive memorie cache.

In questo tipo di situazione, il flusso di transazioni poteva velocemente saturare il bus. Per lungo tempo Intel
ha semplicemente lavorato attorno al problema usando un bus più veloce o memorie cache più ampie, ma
Nehalem è l’opportunità di risolvere il problema alla radice, rivedendo completamente il modo in cui i
processori comunicano con la memoria e i componenti esterni.

La soluzione scelta da Intel – chiamata QuickPath Interconnect (QPI) – non è nuova; un controller di memoria
integrato è un bus seriale punto-punto veramente veloce.
Da un punto di vista tecnico, il collegamento QPI è bidirezionale e ha due collegamenti a 20 bit – uno in ogni
direzione – di cui 16 sono riservati per i dati; gli altri quattro sono usati per i codici di error detection o funzioni
di protocollo. Il bus QPI gestisce un massimo di 6.4 GT/s (miliardi di trasferimenti al secondo) o un bandwidth
di 12.8 GB/s, sia in lettura che in scrittura.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Un collegamento QPI ha perciò un bandwidth teorico fino a 20


due volte maggiore, fermo restando letture e scritture ben
bilanciate.

- Connessioni dirette multiple: più componenti


all'interno del sistema godono di connessioni dirette a
coppie con altri componenti
- Architettura di protocollo a strati/livelli (layer): come
si trova negli ambienti di rete
- Trasferimento dati a pacchetto: i dati non vengono
inviati come flusso di bit non elaborato ma inviati
come una sequenza di pacchetti, ognuno dei quali
include intestazioni di controllo e codici di controllo
degli errori.

Livelli QPI
- Fisico: è costituito dai cavi, circuiti e logica per
supportare le funzioni ausiliarie per trasmissione e
ricezione bit. L'unità di trasferimento a livello fisico è
di 20 bit, chiamata Phit (unità fisica).
- Link: responsabile della trasmissione affidabile e del controllo del flusso. L'unità di trasferimento è
un Flit (unità di controllo del flusso) a 80 bit.
- Routing: fornisce la struttura per dirigere i pacchetti attraverso la struttura.
- Protocollo: l'insieme di regole di alto livello per lo scambio di pacchetti di dati tra dispositivi. Un
pacchetto è composto da un numero intero di 104 Flits.

In particolare:
- Il livello fisico è composto da una serie di percorsi di trasmissione e ricezione, tale che si realizzi una
distribuzione multilinea
- Il livello link, che usa un protocollo con pacchetti da 72 (dati/messaggi) + 8 (codice correzione di
errore) bit
o Due funzioni:
▪ controllo del flusso: evita che il mittente invii più dati di quanti il destinatario possa
ricevere (sistema a crediti)
▪ controllo dell’errore: 8 bit sono utilizzati per rilevare errori di trasmissione sui 72
bit di dati/messaggi (vedremo in seguito come funziona); in caso di errore il
mittente deve re-inviare il pacchetto con l’errore (e altri successivamente inviati)
- Il livello routing (instradamento), che determina il percorso che un pacchetto deve seguire
all’interno del sistema. Supportato da:
o Tabelle di instradamento:
▪ definite dal firmware;
▪ descrivono i possibili percorsi che un pacchetto può seguire;
▪ utile soprattutto in sistemi di dimensione maggiore;
- Il livello protocollo, con un pacchetto definito come unità di trasferimento
o Caratteristiche:
▪ definizione contenuto pacchetto flessibile, in modo da coprire esigenze diverse;
▪ supporta protocollo di coerenza della cache, in modo da garantire coerenza fra i
contenuti delle cache dei core e la memoria principale

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

21
Gerarchie di memoria
Le caratteristiche principali delle memorie sono così condensate:
- Locazione: processore, interna (principale), esterna (secondaria)
- Capacità: dimensione parola, numero di parole
- Unità di trasferimento: parola, blocco
- Metodo di accesso: sequenziale, diretto, casuale, associativo
- Prestazioni: tempo di accesso, tempo di ciclo, velocità trasferimento
- Modello fisico: a semiconduttore, magnetico, ottico, magneticoottico
- Caratteristiche fisiche: volatile/non volatile, riscrivibile/non riscrivibile
- Organizzazione

L’ideale in termini di memoria è disporre di una memoria molto ampia, molto veloce e molto economica.
Graficamente, si ha questo confronto:

Le CPU hanno avuto un aumento di prestazioni notevole, dovuto ad innovazioni tecnologiche ed


architetturali. Le memorie sono migliorate solo grazie agli avanzamenti tecnologici; chiaramente, con esse
sono aumentate sempre di pià le esigenze di memoria da parte dei singoli programmi.
Essi hanno le seguenti proprietà:
- Proprietà statiche (dal file sorgente)
- Proprietà dinamiche (dall’esecuzione)
o Linearità dei riferimenti
▪ Gli indirizzi acceduti sono spesso consecutivi
- Località dei riferimenti
o Località spaziale
▪ Gli accessi ad indirizzi contigui sono più probabili
o Località temporale
▪ La zona di accesso più recente è quella di permanenza più probabile

Da qui, la congettura 90/10, per cui “Un programma impiega mediamente il 90% del suo tempo di
esecuzione alle prese con un numero di istruzioni pari a circa il 10% di tutte quelle che lo compongono”.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Conviene quindi organizzare la memoria su più 22


livelli gerarchici:
- Livello 1 (cache): molto veloce e molto
costosa → dimensioni ridotte, per i dati
ad accesso più
probabile [anche più livelli di cache]
- Livello 2 (memoria centrale): molto
ampia e lenta → costo contenuto, per
tutti i dati del
programma
Al livello più basso (inferiore) stanno i “supporti
di memoria” più capaci, più lenti e meno
costosi, mentre ai livelli più alti (superiori) si
pongono supporti più veloci, più costosi e meno
capaci. La CPU usa direttamente il livello più
alto ed ogni livello inferiore deve contenere
tutti i dati presenti ai livelli superiori (ed altri).

Per realizzare un’organizzazione gerarchica conviene suddividere la memoria in blocchi. La dimensione di un


blocco è la quantità minima indivisibile di dati che occorre prelevare (copiare) dal livello inferiore.
L’indirizzo di un dato diviene l’indirizzo del blocco che lo contiene sommato alla posizione del dato
all’interno del blocco. Due esempi, rispettivamente per cache e per RAM, per cui normalmente si cerca di
avere una memoria ad accesso veloce (cache) che, se non dispone dei dati utili, se li cerca nel disco e
memorizza continuativamente una serie di dati scambiati direttamente a stretto contatto con la RAM.

Un dato richiesto dalla CPU può essere presente in cache (hit) oppure mancante (miss)
- Un hit, successo, deve essere molto probabile (>90%) se si vuole guadagnare efficienza
prestazionale
- Un miss, fallimento, richiede l’avvio di una procedura di scambio dati (swap) con il livello inferiore

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il tempo medio di accesso è così misurato: 23

La tecnica generale, comunque:


- Suddivisione della memoria
centrale in blocchi logici
- Dimensionamento della cache in
multiplo di blocchi
- Per ogni indirizzo emesso dalla
CPU
o Hit → Il dato richiesto
viene fornito
immediatamente alla CPU
o Miss → La cache richiede il
dato al livello inferiore, il
blocco contenente il dato
viene posto in cache ed il
dato richiesto viene
fornito alla CPU

La memoria cache può essere collocata su


entrambi i lati di un'unità di gestione della
memoria e utilizzare indirizzi fisici o logici come
dati di tag. In termini di prestazioni, la posizione
della cache può influire notevolmente sulle
prestazioni del sistema. In una cache logica, le
informazioni di tag si riferiscono agli indirizzi
logici attualmente in uso dal task in esecuzione.

Se l'attività viene interrotta durante un cambio di


contesto, i tag della cache non sono più validi e la
cache, insieme ai suoi dati spesso conquistati con
fatica, deve essere svuotata e cancellata. Il
processore deve andare alla memoria principale
per recuperare le prime istruzioni e attendere la
seconda iterazione prima di ottenere qualsiasi
beneficio dalla cache.

Le cache fisiche utilizzano indirizzi fisici, non necessitano di flush su un cambio di contesto e quindi i dati
vengono conservati all'interno della cache. Lo svantaggio è che tutti gli accessi devono passare attraverso

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

l'unità di gestione della memoria, con conseguenti ritardi. Occorre prestare particolare attenzione anche 24
quando le pagine vengono scambiate da e verso il disco.
Se il processore non invalida le voci della cache associate, il contenuto della cache sarà diverso da quello
della memoria principale a causa della nuova pagina che è stata scambiata.

Problematiche
- Organizzazione della cache e tecniche di allocazione
- Individuazione di hit o miss
- Politica di rimpiazzo dei blocchi
- Congruenza dei blocchi

Memorizzazione ed organizzazione (Mapping della cache)


Esistono tre diversi tipi di mappatura utilizzati per la memoria cache.

1) Mappatura diretta/Direct Mapping


La tecnica più semplice, nota come mappatura diretta, mappa ogni blocco di memoria principale in una sola
possibile linea di cache. Nella mappatura diretta, ogni blocco di memoria viene assegnato a una linea
specifica della cache. Se una riga è stata precedentemente occupata da un blocco di memoria, quando deve
essere caricato un nuovo blocco, il vecchio blocco viene cestinato. Uno spazio di indirizzi è diviso in due
parti: un campo indice e un campo tag. La cache viene utilizzata per memorizzare il campo tag, mentre il
resto viene memorizzato nella memoria principale. Le prestazioni della mappatura diretta sono
direttamente proporzionali alla possibilità di avere una Hit.

Il numero di riga della cache in cui può essere mappato un determinato blocco è dato da:

𝑁𝑢𝑚𝑒𝑟𝑜 𝑑𝑖 𝑙𝑖𝑛𝑒𝑎 𝑑𝑒𝑙𝑙𝑎 𝑐𝑎𝑐ℎ𝑒 =


( 𝐼𝑛𝑑𝑖𝑟𝑖𝑧𝑧𝑜 𝑑𝑒𝑙 𝑏𝑙𝑜𝑐𝑐𝑜 𝑑𝑖 𝑚𝑒𝑚𝑜𝑟𝑖𝑎 𝑝𝑟𝑖𝑛𝑐𝑖𝑝𝑎𝑙𝑒 ) 𝑚𝑜𝑑 (𝑁𝑢𝑚𝑒𝑟𝑜 𝑑𝑖 𝑟𝑖𝑔ℎ𝑒 𝑛𝑒𝑙𝑙𝑎 𝑐𝑎𝑐ℎ𝑒)

Ai fini dell'accesso alla cache, ogni indirizzo di memoria principale può essere considerato come composto
da tre campi. I bit w meno significativi identificano una parola o un byte unico all'interno di un blocco di
memoria principale. Nella maggior parte delle macchine moderne, l'indirizzo è a livello di byte. I restanti bit
s specificano uno dei 2𝑠 blocchi di memoria principale. La logica della cache interpreta questi bit 𝑠 come un
tag di 𝑠 − 𝑟 bit (porzione più significativa) e un campo di riga di 𝑟 bit. Quest'ultimo campo identifica una
delle 𝑚 = 2𝑟 linee della cache.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

25

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I passaggi seguenti spiegano il funzionamento della cache a mappatura diretta. 26


La CPU genera una richiesta di memoria:
- Il campo del numero di riga dell'indirizzo viene utilizzato per accedere a una particolare riga della
cache.
- Il campo tag dell'indirizzo della CPU viene quindi confrontato con il tag della riga.
- Se i due tag corrispondono, si verifica una cache hit e la parola desiderata viene trovata nella cache.
- Se i due tag non corrispondono, si verifica una cache miss.
- In caso di cache miss, la parola desiderata deve essere prelevata dalla memoria principale.
- Viene quindi memorizzata nella cache insieme al nuovo tag che sostituisce quello precedente.

Vantaggi
- Semplicità di traduzione da indirizzo ILI (memoria) ad indirizzo ILS (cache)
- Determinazione veloce di hit o miss
Svantaggi
- Necessità di contraddistinguere il blocco presente in ILS (introduzione di un’etichetta, ‘tag’)
- Swap frequenti per accesso a dati di blocchi adiacenti

2) Associative mapping/Mapping associativo

In questo tipo di mappatura, la memoria associativa viene utilizzata per memorizzare il contenuto e gli
indirizzi delle parole di memoria. Qualsiasi blocco può essere inserito in qualsiasi riga della cache. Ciò
significa che i bit dell'id della parola vengono utilizzati per identificare quale parola del blocco è necessaria,
ma il tag diventa tutti i bit rimanenti. Ciò consente di collocare qualsiasi parola in qualsiasi punto della
memoria cache. È considerata la forma di mappatura più veloce e flessibile.
Ogni blocco del livello inferiore può essere posto in qualunque posizione del livello superiore.

Questo metodo di ricerca di un blocco all'interno della cache sembra essere un processo lento, ma non è
così. Ogni riga della cache ha il suo circuito di confronto, che può analizzare rapidamente se il blocco è
contenuto o meno in quella riga. Poiché tutte le linee eseguono questo processo di confronto in parallelo,
la linea corretta viene identificata rapidamente.

Questa tecnica di mappatura è stata progettata per risolvere un problema che esiste con la mappatura
diretta, in cui due blocchi di memoria attivi possono essere mappati sulla stessa riga della cache. In questo
caso, nessuno dei due blocchi di memoria può rimanere nella cache perché viene sostituito rapidamente
dal blocco concorrente. Questo porta a una condizione che viene definita thrashing.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Nel thrashing, una riga della cache va avanti e indietro tra due o più blocchi, di solito sostituendo un blocco 27
prima ancora che il processore lo abbia superato. Il thrashing può essere evitato consentendo la mappatura
di un blocco di memoria su qualsiasi linea della cache. È necessario un algoritmo di sostituzione per
sostituire un blocco se la cache è piena.

Alla cache capace di N blocchi viene associata una tabella di N posizioni, contenenti il numero di blocco
effettivo (tag) in essa contenuto.
Vantaggi
- Massima efficienza di allocazione
Svantaggi
- Determinazione onerosa della corrispondenza ILS-ILI e della verifica di hit/mis

3) Associazione a gruppi / N-way set associative

Ogni blocco di un certo insieme di blocchi del livello inferiore può essere allocato liberamente in uno
specifico gruppo di blocchi del livello superiore. Questa forma di mappatura è una forma migliorata di
mappatura diretta, in cui gli svantaggi della mappatura diretta vengono eliminati. Il set associativo risolve il
problema del possibile thrashing del metodo di mappatura diretta. A tal fine, invece di avere esattamente
una riga a cui un blocco può fare da mappatura nella cache, si raggruppano alcune righe creando un
insieme. La mappatura associativa a set permette che ogni parola presente nella cache possa avere due o
più parole nella memoria principale per lo stesso indirizzo di indice. La mappatura associativa a set combina
il meglio delle tecniche di mappatura diretta e associativa della cache.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Un indirizzo di cache può essere suddiviso in 3 parti. 28


- l'offset all'interno del blocco
- l'indice che identifica l'insieme
- il tag che identifica il blocco nell'insieme.
Quando arriva una richiesta, viene calcolato l'indice per identificare l'insieme. Poi vengono controllati i tag
di tutti i blocchi dell'insieme. Quando viene trovato un blocco con un tag corrispondente, vengono restituiti
i byte giusti in base all'offset.
Una cache a mappatura diretta è di fatto una cache associativa a 1 via.
Il grande vantaggio di una cache associativa a n vie rispetto a una cache a mappatura diretta è che
quest'ultima può contenere un solo blocco per un insieme di indirizzi, mentre la prima può contenere più
blocchi per un insieme di indirizzi.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Alla cache, composta da R gruppi di N posizioni di blocco ciascuno, si affiancano R tabelle di N elementi,
contenenti le etichette (tag) che designano i blocchi effettivi posti nelle posizioni corrispondenti 29
- Valutazione: buona efficienza di allocazione a fronte di una sopportabile complessità di ricerca

Politiche di rimpiazzo dei blocchi

Quale blocco conviene sostituire in cache per effettuare uno swap?


(Penalità di miss)
- Casuale, per occupazione omogenea dello spazio
- First-In-First-Out (FIFO), per
sostituire il blocco rimasto più a
lungo in cache
- Least Frequently Used (LFU), per
sostituire il blocco con meno accessi
Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Least Recently Used (LRU), per


preservare località temporale 30

Problema della scrittura

La scrittura dei dati determina incoerenza tra il blocco in cache e quello nei livelli inferiori.
- ‘Write through’
o Scrittura contemporanea in cache e nel livello di memoria inferiore
o Aumento di traffico per frequenti scritture nel medesimo blocco, ma i dati sono sempre
coerenti tra i livelli
o Si ricorre a buffer di scrittura asincroni (differiti) verso la memoria
- ‘Write back’
o Scrittura in memoria inferiore differita al rimpiazzo del blocco di cache corrispondente
o Occorre ricordare se sono avvenute operazioni di scrittura nel blocco
o Consente ottimizzazione del traffico tra livelli
o Causa periodi di incoerenza (problemi con moduli di I/O e multiprocessori con cache locale)
Scenario particolarmente problematico: più dispositivi (es. processori) connessi allo stesso bus con cache
locale e memoria centrale condivisa

Possibili soluzioni
- Monitoraggio del bus con write through
o Controllori cache intercettano modifiche locazioni condivise
- Trasparenza hardware
o Hardware aggiuntivo: modifica a M ® modifica tutte cache
- Memoria noncacheable
o Solo una porzione di M è condivisa e noncacheable (accessi a M condivisa generano miss)
- Modifica dati in una cache
o invalida la parola corrispondente in memoria centrale
o invalida la parola corrispondente nelle altre cache che la contengono
o write through non risolve il problema (risolve solo l’inconsistenza della memoria centrale)

Il problema dei ‘miss’

- Miss di primo accesso, inevitabile e non riducibile


- Miss per capacità insufficiente, quando la cache non può contenere tutti i blocchi necessari
all’esecuzione del programma
- Miss per conflitto, quando più blocchi possono essere mappati (con associazione diretta o a gruppi)
su uno stesso gruppo

Possibili soluzioni

- Maggior dimensione di blocco


o Buona per fruire di località spaziale
o Causa incremento di miss per conflitto (meno blocchi disponibili)
o Maggiore associatività
- Causa incremento del tempo di localizzazione in gruppo (hit)
- Soggetta alla ‘regola del 2:1’
o Una cache ad N blocchi con associazione diretta ha una probabilità di miss pressoché
uguale ad una cache di dimensione N/2 con associazione a 2 vie
- Altre tecniche:
o Cache multilivello (cache on-chip L1 e/o L2 e/o L3)
o Separazione tra cache dati e cache istruzioni
o Ottimizzazione degli accessi mediante compilatori
▪ Posizionamento accurato delle procedure ripetitive
Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

▪ Fusione di vettori in strutture (località spaziale)


▪ Trasformazioni di iterazioni annidate (località spaziale) 31

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

32
Esercizi cache 1

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

33

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

34

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

35

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

36

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

37

Memorie interne
La memoria a semiconduttori è una memoria informatica in cui le informazioni e i dati sono registrati
mediante le tecnologie dei semiconduttori, ( transistor, circuiti integrati, chip, ecc ). È una delle principali
componenti della memoria centrale del computer. La memoria a semiconduttori è composta da celle
elementari, ognuna delle quali può contenere un'informazione ( bit ) sotto forma di carica elettrica di un
condensatore, che compongono una matrice simile a una bacheca/lavagna digitale. Le memorie a
semiconduttori i sono prevalentemente delle memorie volatili, i dati sono mantenuti in memoria fin
quando il dispositivo è alimentato dalla corrente elettrica. Al momento dello spegnimento l'informazione
viene perduta. Sono utilizzate nella memoria centrale del computer.

Le memorie sono classificare in:


- Memoria RAM (Random Access Memory), ad accesso casual, memoria volatile a memorizzazione
temporanea (quindi allo spegnimento del computer i dati sono automaticamente cancellati).
Esiste una distinzione ulteriore, in particolare può essere:
1) RAM Dinamica (Dynamic RAM)
o Bit memorizzati come cariche in condensatori
o Decadimento delle cariche con il tempo
o Necessitano di refresh delle cariche, anche durante l’alimentazione
o Costruzione più semplice
o Un condensatore per bit
o Meno costose
o Necessitano di circuiti per il refresh
o Più lente
o Usate per la memoria principale
o In essenza operano in modo analogico
▪ Il livello di carica determina il valore digitale

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

La memoria dinamica ad accesso casuale (DRAM) è 38


un tipo di memoria a semiconduttore utilizzata in
genere per i dati o il codice di programma necessari
al funzionamento di un processore di computer. La
DRAM è un tipo comune di memoria ad accesso
casuale (RAM) utilizzata nei personal computer (PC),
nelle workstation e nei server. L'accesso casuale
consente al processore del PC di accedere
direttamente a qualsiasi parte della memoria,
anziché procedere in sequenza da un punto di
partenza. La RAM si trova vicino al processore del
computer e consente un accesso più rapido ai dati
rispetto ai supporti di memorizzazione come i dischi
rigidi e le unità a stato solido.

Come funziona la DRAM?


La memoria è costituita da bit di dati o codice di programma disposti in una griglia bidimensionale. La
DRAM memorizza i bit di dati in una cosiddetta cella di memoria, composta da un condensatore e da un
transistor. Le celle di memoria sono tipicamente organizzate in una configurazione rettangolare. Quando
una carica viene inviata attraverso una colonna, il transistor sulla colonna viene attivato. Una cella di
memoria DRAM è dinamica, il che significa che deve essere rinfrescata o ricevere una nuova carica
elettronica ogni pochi millisecondi per compensare le perdite di carica dal condensatore.

Le celle di memoria funzionano con altri circuiti che possono essere utilizzati per identificare le righe e le
colonne, seguire il processo di aggiornamento, indicare a una cella se accettare o meno una carica e leggere
o ripristinare i dati da una cella.

La DRAM è una delle opzioni di memoria a semiconduttore che il progettista di un sistema può utilizzare
nella costruzione di un computer. Altre opzioni di memoria sono la RAM statica (SRAM), la memoria di sola
lettura programmabile e cancellabile elettricamente (EEPROM), la memoria flash NOR e la memoria flash
NAND. Molti sistemi utilizzano più di un tipo di memoria.

Funzionamento DRAM
- Linea indirizzo attivata quando si deve scrivere o leggere un bit
o Transistor “chiuso” (la corrente fluisce)
- Write
o Si applica tensione alla linea di bit
▪ Tensione alta indica valore 1; tensione bassa indica valore 0
o Poi si applica un segnale alla linea indirizzo
▪ Trasferisce la carica al condensatore
- Read
o Si seleziona la linea indirizzo
▪ Il transistor si accende
- La carica del condensatore fluisce attraverso la linea di bit verso un amplificatore
o Valore di carica comparato con un segnale di riferimento per stabilire se vale 0 o 1
- La carica del condensatore deve essere ristabilita (refresh)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

RAM Statica 39
- Bit memorizzati tramite porte logiche
- Nessuna perdita di carica
- Nessuna necessità di refresh
- Costruzione più complessa
- Più elementi per bit
- Più costosa
- Non ha bisogno di circuiti di refresh
- Più veloci
- Usate per la cache
- Digitale
o usa flip-flop

La SRAM o Static Random Access Memory (memoria statica ad accesso casuale) è una forma di memoria a
semiconduttore ampiamente utilizzata nell'elettronica, nei microprocessori e nelle applicazioni
informatiche in generale.
Questa forma di memoria per computer deve il suo nome al fatto che i dati sono conservati nel chip di
memoria in modo statico e non devono essere aggiornati dinamicamente come nel caso della memoria
DRAM.

Sebbene i dati nella memoria SRAM non debbano essere aggiornati dinamicamente, sono comunque
volatili, il che significa che quando l'alimentazione viene rimossa dal dispositivo di memoria, i dati non
vengono conservati e scompaiono.
La S-RAM ha il vantaggio di offrire prestazioni migliori rispetto alla DRAM, perché quest'ultima deve essere
aggiornata periodicamente quando è in uso, mentre la SRAM non lo fa. Tuttavia, la SRAM è più costosa e
meno densa della DRAM, per cui le dimensioni della SRAM sono di ordini di grandezza inferiori rispetto alla
DRAM.

Nozioni di base sulle SRAM


Le caratteristiche principali della SRAM (Static Random Access Memory) sono due e la distinguono dagli
altri tipi di memoria disponibili:
- I dati sono conservati in modo statico: Ciò significa che i dati sono conservati nella memoria a
semiconduttore senza bisogno di essere aggiornati finché la memoria è alimentata.
- La memoria SRAM è una forma di memoria ad accesso casuale: Una memoria ad accesso casuale è
una memoria in cui le posizioni nella memoria a semiconduttore possono essere scritte o lette in
qualsiasi ordine, indipendentemente dall'ultima posizione di memoria a cui si è acceduto.
Il circuito di una singola cella di memoria SRAM comprende in genere quattro transistor configurati come
due invertitori accoppiati a croce. In questo formato il circuito ha due stati stabili, che equivalgono agli stati
logici "0" e "1".

I transistor sono MOSFET (metal–oxide–semiconductor field-effect transistor) perché la quantità di energia


consumata da un circuito MOS è notevolmente inferiore a quella della tecnologia dei transistor bipolari,
che è l'altra opzione praticabile, ma consuma molto di più.

L'uso della tecnologia bipolare limita il livello di integrazione perché la questione della rimozione del calore
diventa un problema importante. Per questo motivo la tecnologia bipolare viene utilizzata raramente.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Vantaggi 40
I principali vantaggi della DRAM sono i seguenti:
- Il suo design è semplice e richiede un solo transistor.
- Il costo è basso rispetto a tipi di memoria alternativi come la SRAM.
- Offre livelli di densità più elevati.
- Con la DRAM si possono memorizzare più dati.
- La memoria può essere aggiornata e cancellata durante l'esecuzione di un programma.

Svantaggi
I principali svantaggi della DRAM sono i seguenti:
- La memoria è volatile.
- Il consumo di energia è elevato rispetto ad altre opzioni.
- La produzione è complessa.
- I dati nelle celle di memoria devono essere aggiornati.
- È più lenta della SRAM.

Oltre ai quattro transistor della cella di memoria di base, sono necessari altri due transistor per controllare
l'accesso alla cella di memoria durante le operazioni di lettura e scrittura.
In questo modo si arriva a un totale di sei transistor, che danno vita alla cosiddetta cella di memoria a 6T,
che, sebbene più complessa in termini di numero di componenti, presenta una serie di vantaggi.

Il vantaggio principale del circuito SRAM a sei transistor è la riduzione della potenza statica. Nella versione a
quattro transistor, c'è un flusso di corrente costante attraverso l'uno o l'altro dei resistori di pull down e
questo aumenta il consumo energetico complessivo del chip. Ciò può limitare il livello di integrazione e
aumentare i problemi di progettazione dei circuiti a causa della maggiore dissipazione di potenza.

Vale la pena di ricordare che la cella di memoria SRAM a quattro transistor offre alcuni vantaggi in termini
di densità, ma ciò comporta una maggiore complessità di produzione, in quanto è necessario fabbricare le
resistenze e ciò richiede una lavorazione aggiuntiva. Inoltre, i resistori devono avere dimensioni ridotte e
valori elevati per soddisfare i requisiti della cella.

Funzionamento RAM Statica

- La disposizione dei transistor garantisce stati stabili


- Stato 1
o C1 alto, C2 basso
o T1 T4 “spenti”, T2 T3 “accesi”,
- Stato 0
o C2 alto, C1 basso
o T2 T3 “spenti”, T1 T4 “accesi”,
- La linea indirizzo controlla i transistor T5 T6 (accesi con presenza di segnale)
- Write – si applica il valore da scrivere alla linea B ed il complemento del valore alla linea B
- Read – il valore viene letto tramite la linea B

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

SRAM DRAM 41
La SRAM ha un tempo di accesso inferiore, più veloce La DRAM ha un tempo di accesso più elevato. È più lenta
rispetto alla DRAM. della SRAM.
La SRAM è più costosa della DRAM. Il costo della DRAM è inferiore a quello della SRAM.
La SRAM ha bisogno di un'alimentazione costante, ma La DRAM richiede un consumo maggiore di energia,
consuma meno energia. poiché le informazioni sono memorizzate nel
condensatore.
La SRAM offre una bassa densità di packaging. La DRAM offre un'elevata densità di packaging.
Utilizza transistor e latches. Utilizza condensatori e pochissimi transistor.
Le unità cache L2 e L3 della CPU sono alcune applicazioni La DRAM è la memoria principale dei computer.
generali di una SRAM.
La capacità di memorizzazione della SRAM va da 1MB a La capacità di memoria della DRAM va da 1 GB a 16 GB.
16MB.
La SRAM si presenta sotto forma di memoria on-chip. La DRAM ha le caratteristiche di una memoria off-chip.
La SRAM è ampiamente utilizzata sul processore o collocata La DRAM è collocata sulla scheda madre.
tra la memoria principale e il processore del computer.
La SRAM è di dimensioni più piccole. La DRAM è disponibile con una capacità di memoria
maggiore.
Questo tipo di RAM funziona in base al principio di Questo tipo di RAM funziona con il mantenimento delle
cambiare la direzione della corrente attraverso degli cariche.
interruttori.

Read Only Memory (ROM)


- Memorizzazione permanente
o Non volatili
- Usate per memorizzare:
o Microprogrammi (Nella progettazione dei processori, il microcodice è una tecnica che
interpone uno strato di organizzazione informatica tra l'hardware dell'unità di elaborazione
centrale (CPU) e l'architettura del set di istruzioni visibile al programmatore di un
computer. Il microcodice è uno strato di istruzioni a livello hardware che implementa
istruzioni di codice macchina di livello superiore o sequenze interne di macchine a stati
finiti in molti elementi di elaborazione digitale. Il microcodice è utilizzato nelle unità di
elaborazione centrale di uso generale, anche se nelle CPU desktop attuali è solo un
percorso di ripiego per i casi che l'unità di controllo cablata più veloce non è in grado di
gestire. La scrittura di microcodice è spesso chiamata microprogrammazione e il
microcodice di una particolare implementazione del processore è talvolta chiamato
microprogramma.)

o subroutine di libreria (Le subroutine vengono memorizzate in librerie per risparmiare


spazio e rendere più efficiente il processo di collegamento dei programmi. Una libreria è un
file di dati che contiene copie di un certo numero di file individuali e informazioni di
controllo che consentono di accedervi singolarmente).

o programmi di sistema (BIOS) (BIOS, in inglese Basic Input/Output System, programma per
computer tipicamente memorizzato in EPROM e utilizzato dalla CPU per eseguire le
procedure di avvio all'accensione del computer. Le sue due procedure principali sono la
determinazione dei dispositivi periferici (tastiera, mouse, unità disco, stampanti, schede
video, ecc.) disponibili e il caricamento del sistema operativo (OS) nella memoria principale)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

La memoria di sola lettura (ROM) è un tipo di supporto di archiviazione che memorizza in modo 42
permanente i dati nei personal computer (PC) e in altri dispositivi elettronici.
Contiene la programmazione necessaria per avviare un PC, essenziale per l'avvio; esegue le principali
operazioni di input/output e contiene programmi o istruzioni software. Questo tipo di memoria viene
spesso definito "firmware" e la sua modifica è stata una fonte di considerazione per la progettazione nel
corso dell'evoluzione del computer moderno.

Tipi di ROM
- Scritte in produzione
o Molto costoso per pochi “pezzi”
- Programmabili (una sola volta)
o PROM
o Necessitano di strumentazione speciale per la programmazione
- Principalmente di lettura (Read “mostly”)
o Erasable Programmable (EPROM)
▪ Si cancellano (per intero) tramite raggi ultravioletti
- Electrically Erasable (EEPROM)
o Impiegano molto più tempo per la scrittura che per la lettura
- Memorie Flash
o Cancellazione elettrica di blocchi di memoria

Ecco una panoramica dei diversi tipi di ROM, dai più semplici ai più versatili.

- ROM: i chip ROM classici o "programmati a maschera" contengono circuiti integrati. Un chip ROM
invia una corrente attraverso uno specifico percorso di input-output determinato dalla posizione
dei fusibili tra le righe e le colonne del chip. La corrente può viaggiare solo lungo un percorso
abilitato dai fusibili e quindi può tornare solo attraverso l'uscita scelta dal produttore. Il ricablaggio
è funzionalmente impossibile e quindi non c'è modo di modificare questi tipi di chip ROM. Mentre
la produzione di un modello per un chip ROM originale è laboriosa, i chip realizzati secondo un
modello esistente possono essere molto più convenienti.

- PROM: la ROM programmabile, o PROM, è essenzialmente una versione vuota della ROM che può
essere acquistata e programmata una volta con l'aiuto di uno strumento speciale chiamato
programmatore. Un chip PROM vuoto permette alla corrente di passare attraverso tutti i percorsi
possibili; il programmatore sceglie un percorso per la corrente inviando un'alta tensione attraverso
i fusibili indesiderati per "bruciarli". L'elettricità statica può creare accidentalmente lo stesso
effetto, quindi le PROM sono più vulnerabili ai danni rispetto alle ROM convenzionali.

- EPROM: i chip ROM programmabili e cancellabili consentono di scrivere e riscrivere più volte.
Questi chip sono dotati di una finestra di quarzo attraverso la quale un programmatore EPROM
specializzato emette una specifica frequenza di luce ultravioletta. Questa luce brucia tutte le
piccole cariche presenti nella EPROM per riaprirne i circuiti. Questa esposizione rende il chip
nuovamente vuoto, dopodiché è possibile riprogrammarlo secondo lo stesso processo di una
PROM. I chip EPROM finiscono per consumarsi, ma spesso hanno una durata di vita superiore a
1000 cancellazioni.

- EEPROM: per modificare un chip ROM programmabile elettricamente cancellabile, si applicano


campi elettrici localizzati per cancellare e riscrivere i dati. Le EEPROM presentano diversi vantaggi
rispetto ad altri tipi di ROM. A differenza delle forme precedenti, è possibile riscrivere la EEPROM
senza apparecchiature dedicate, senza rimuoverla dall'hardware e in incrementi specificamente
designati. Non è necessario cancellare e riscrivere tutto per effettuare una singola modifica.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Memorie flash: La memoria flash è un tipo di EEPROM progettata per l'alta velocità e la densità di
memoria. Pertanto, le unità flash basati su questa tecnologia possono memorizzare molti gigabyte 43
di dati su una chiavetta USB più piccola di un pollice. Sviluppando ulteriormente questo design
compatto, le schede micro SD sono grandi come un'unghia e possono comunemente memorizzare
decine o addirittura centinaia di gigabyte di informazioni. Su una scala più ampia, si potrebbero
stipare ancora più dati su questo tipo di memoria, forse abbastanza da fungere da metodo di
memorizzazione primaria del computer. Le schede sono più o meno delle dimensioni di un'unghia e
possono comunemente memorizzare decine o addirittura centinaia di gigabyte di informazioni. Su
una scala più ampia, si potrebbero stipare ancora più dati su questo tipo di memoria, forse
abbastanza da fungere da metodo di memorizzazione primaria del computer.

I guasti possono essere di due tipi:


- Guasti Hardware (Hard Failure)ù
o Guasti permanenti
- Errori Software (Soft Error)
o Random, non-distruttivi
Danni alla memoria non permanenti
- Errori rilevati ed eventualmente corretti usando, ad esempio, codici correttori di Hamming.

Una sequenza di n bit composta da 𝑚 bit di dati e di 𝑟 bit di controllo, con 𝑛 = 𝑚 + 𝑟, viene chiamata
parola di codice (codeword) su 𝑛 bit.
Il numero di bit diversi tra due parole di codice viene detto distanza di Hamming; si può calcolare il numero
di bit diversi facendo l’or esclusivo delle due stringhe e contando il numero di bit 1 del risultato; se due
parole hanno distanza d significa che servono d errori per trasformare una nell’altra.

In genere non tutte le possibili stringhe di n bit (2n) sono legali (anche se quelle con m bit di dati lo sono); la
distanza minima tra le parole legali del codice è la distanza di Hamming del codice.
La distanza di Hamming indica quanti errori si possono rilevare e quanti se ne possono correggere.
Per rilevare d errori serve una distanza di 𝑑 + 1; per correggere d errori serve una distanza di 2𝑑 + 1 (la
parola originale è la più vicina valida).

Il codice di Hamming è un codice che permette di aggiungere un certo numero di bit ai bit di dati in modo
da comporre parole con distanza 3, in grado di rilevare e correggere errori su un singolo bit. Il numero di bit
da aggiungere aumenta all’aumentare del numero dei bit di dati.
I bit aggiunti sono bit di parità calcolati su sottoinsiemi di bit della parola di codice; numerando a partire da
1 a sinistra i bit che compongono la parola di codice, i bit di parità vengono inseriti nelle posizioni che sono
potenze di 2 (1, 2, 4, 8, 16 …); gli altri bit sono i bit di dati.

Ogni bit di parità viene calcolato su un sottoinsieme di bit; ogni bit di dati può essere incluso in diversi
sottoinsiemi e influire su diversi bit di parità. Per sapere su quali bit di parità influisce il bit di dati k, basta
riscrivere k come somma di potenze di 2 (per esempio 11 = 1 + 2 + 8); ogni bit di dati è controllato da tutti e
soli i bit di parità che appartengono alla sua espansione (il bit 11 è controllato dai bit 1, 2 e 8).
Al momento del controllo, per ogni parola di codice vengono ricalcolati i bit di parità per ogni posizione k
(con k = 1, 2, 4, 8, 16…). Se la parità non è corretta viene aggiunto k a un contatore inizializzato a 0; al
termine il valore del contatore indica la posizione del bit errato (se non sono corretti i bit di parità 1, 2 e 8 il
bit errato è quello in posizione 11).

Partendo dalla sequenza:


0110
(1 2 3 4)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

si calcolano e inseriscono i bit di parità nelle posizioni 1, 2 e 4:


__0_110 44
(1 2 3 4 5 6 7)
quindi i bit di dati occupano le posizioni 3, 5, 6 e 7.

Il bit 3 influenza i bit di parità 1 e 2 (3=1+2).

Il bit 5 influenza i bit di parità 1 e 4 (5=1+4).

Il bit 6 influenza i bit di parità 2 e 4 (6=2+4).

Il bit 7 influenza i bit di parità 1, 2 e 4 (7=1+2+4).

Il bit di parità 1 è calcolato sui bit di dati 3, 5 e 7 (0 1 0) e quindi vale 1.

Il bit di parità 2 è calcolato sui bit di dati 3, 6 e 7 (0 1 0) e quindi vale 1.

Il bit di parità 4 è calcolato sui bit di dati 5, 6 e 7 (1 1 0) e quindi vale 0.

Perciò si ottiene la sequenza:


1100110
Se un errore modifica la sequenza in:
1100100
(1 2 3 4 5 6 7)
ricalcolando i bit di parità si ottiene:

bit di parità 1 calcolato sui bit di dati 3, 5 e 7 (0 1 0): 1

bit di parità 2 calcolato sui bit di dati 3, 6 e 7 (0 0 0): 0

bit di parità 4 calcolato sui bit di dati 5, 6 e 7 (1 0 0): 1

Confrontando i bit della sequenza originale con quelli calcolati viene incrementato il contatore k:

il bit di parità 1 è uguale: k=0;

il bit di parità 2 è diverso: k=2;

il bit di parità 4 è diverso: k=6.

Pertanto, si può stabilire che c’è un bit errato nella posizione 6 e lo si può correggere riottenendo la
sequenza 1 1 0 0 1 1 0.

Lo schema del funzionamento del codice a correzione di errore:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Possiamo anche visualizzare il funzionamento con i diagrammi di Venn. 45


A titolo di esempio, si supponga di voler inviare il messaggio 1101. Associamo ciascuno dei quattro bit del
messaggio a una specifica regione di intersezione di tre cerchi sovrapposti, come illustrato di seguito:

Il codice di Hamming aggiunge tre bit di parità in modo che ogni cerchio abbia una parità pari.

Cioè, la somma dei quattro bit di ciascun cerchio è ora pari:

In questo caso si invia 1101100 poiché i tre bit di parità sono 1 (in alto), 0 (a sinistra) e 0 (a destra).

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Immaginiamo ora che questa immagine venga trasmessa via modem su un canale di comunicazione 46
rumoroso e che un bit venga corrotto in modo tale che alla stazione ricevente arrivi la seguente immagine
(corrispondente a 1001100):

Il ricevitore scopre che si è verificato un errore controllando la parità dei tre cerchi. Inoltre, il ricevitore può
persino determinare dove si è verificato l'errore (il secondo bit) e recuperare i quattro bit del messaggio
originale!

Poiché il controllo di parità per il cerchio superiore e per quello destro non è andato a buon fine, mentre
per quello sinistro era tutto a posto, c'è solo un bit che potrebbe essere responsabile, ovvero m2. Se il bit
centrale, m4, è danneggiato, tutti e tre i controlli di parità falliranno. Se uno stesso bit di parità è
danneggiato, solo un controllo di parità fallirà. Se il collegamento dati è così rumoroso che due o più bit
sono corrotti contemporaneamente, il nostro schema non funziona. Riuscite a capire perché? Codici di
correzione degli errori più sofisticati sono in grado di gestire situazioni di questo tipo.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

47

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

48

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

49

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

50

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

51

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

52

Memorie esterne
La memoria esterna è nota anche come memoria secondaria. Viene utilizzata per memorizzare un'enorme
quantità di dati perché ha un'enorme capacità. Attualmente può misurare i dati in centinaia di megabyte o
addirittura in gigabyte. L'importante proprietà della memoria esterna è che, in caso di spegnimento del
computer, le informazioni memorizzate non andranno perse. La memoria esterna può essere suddivisa in
quattro parti:
1. Disco magnetico
2. Raid
3. Memoria ottica
4. Nastro magnetico

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Dischi magnetici 53

Un disco è un tipo di piatto circolare costruito da un materiale non magnetico, noto come substrato. È
ricoperto da un rivestimento magnetico utilizzato per contenere le informazioni. Il substrato è
tradizionalmente costituito da alluminio o da una lega di alluminio. Recentemente, però, è stato introdotto
un altro materiale, noto come substrato di vetro. I substrati di vetro offrono diversi vantaggi, descritti di
seguito:
o Può aumentare l'affidabilità del disco migliorando l'uniformità della superficie del film magnetico.
o Viene utilizzato per ridurre gli errori di lettura-scrittura grazie a una significativa riduzione dei difetti
superficiali complessivi.
o Ha una migliore rigidità, che contribuisce a ridurre la dinamica del disco. Ha la grande capacità di resistere
agli urti e ai danni.

Memoria magnetica di lettura e scrittura

Il componente più importante della memoria esterna sono ancora i dischi magnetici. Molti sistemi, come
supercomputer, personal computer e mainframe, contengono dischi rigidi sia rimovibili che fissi. È possibile
condurre una bobina, denominata testina, in modo da poter recuperare i dati su e in un secondo momento
e quindi recuperarli dal disco. Molti sistemi contengono due testine: una di lettura e una di scrittura.
Durante le operazioni di lettura e scrittura, il piatto ruota mentre la testina è ferma.

Se l'elettricità scorre attraverso la bobina, il meccanismo di scrittura sfrutta il fatto che la bobina genera un
campo magnetico. La testina di scrittura riceverà gli impulsi elettrici e la superficie sottostante registrerà il
modello magnetico risultante. La registrazione avverrà secondo schemi diversi per correnti negative e
positive. Se l'elettricità scorre attraverso la bobina, il meccanismo di lettura sfrutterà il fatto che genererà
una corrente elettrica nella bobina. Quando la superficie del disco passa sotto la testina, produrrà una
corrente con la stessa polarità di quella già registrata.
In questo caso, la struttura della testina è la stessa per la lettura e la scrittura. Pertanto, è possibile
utilizzare la stessa testina per entrambe. Questi tipi di testine singole possono essere utilizzate nei vecchi
sistemi di dischi rigidi e nei sistemi di dischi floppy. Nella testina di lettura è presente un tipo di sensore
magneto-resistivo (MR) parzialmente schermato. La resistenza elettrica è contenuta nel materiale MR, che
dipende dalla direzione di magnetizzazione del mezzo che si muove sotto di esso.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Organizzazione e formattazione dei dati 54

La testina è un piccolo dispositivo in grado di leggere o scrivere sulla porzione di piatto che ruota sotto di
essa. La larghezza di ogni traccia è uguale a quella della testina. Ci sono migliaia di tracce per ogni
superficie. Gli spazi vuoti vengono utilizzati per indicare la separazione delle tracce adiacenti. In questo
modo è possibile prevenire o ridurre al minimo l'errore generato dall'interferenza dei campi magnetici o dal
disallineamento della testina. I settori sono utilizzati per trasferire i dati da e verso i dischi.

I settori a lunghezza fissa saranno utilizzati nei sistemi più moderni con 512 byte, una dimensione quasi
universale. Gli spazi intersettoriali separano i settori adiacenti in modo da evitare di imporre ai sistemi
requisiti di precisione irragionevoli. Allo stesso tempo, possiamo scansionare le informazioni con l'aiuto
della rotazione del disco a una velocità fissa, chiamata velocità angolare costante (CAV).
I dischi possono essere suddivisi in vari modi. Possono essere suddivisi in una serie di tracce concentriche e
in diversi settori a forma di torta. La CAV ha il vantaggio che le tracce e i settori possono indirizzare
direttamente i dati con l'aiuto della CAV. Il CAV ha anche uno svantaggio: la quantità di dati memorizzati
sulle tracce interne corte e sulle tracce esterne lunghe è la stessa.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I moderni dischi rigidi introducono una tecnica per aumentare la densità, chiamata registrazione a zone 55
multiple. Con questa tecnica, la superficie può essere suddivisa in diverse zone concentriche, che in genere
sono pari a 16, il che significa 16 zone. Il numero di bit per traccia è costante all'interno di una zona. Le zone
più vicine al centro hanno una quantità inferiore di bit o settori rispetto alle zone più lontane dal centro.

Caratteristiche fisiche

Se si tratta di un disco a testine fisse, allora conterrà una testina di lettura-scrittura per traccia. Tutte
queste testine sono montate su un braccio rigido, che può estendersi su tutte le tracce. Se il disco è a
testine mobili, conterrà una sola testina di lettura-scrittura. Anche in questo caso la testina è montata sul
braccio. La testina può posizionarsi sopra qualsiasi traccia. A questo scopo, il braccio può essere retratto o
esteso.
L'unità disco contiene sempre o permanentemente un disco non rimovibile. Ad esempio, nei personal
computer, il disco rigido non può mai essere rimosso, o possiamo dire che è un disco non rimovibile. Il disco
rimovibile è un tipo di disco che può essere rimosso e sostituito con altri dischi. Entrambi i lati del piatto
contengono il rivestimento magnetizzabile per la maggior parte dei dischi, che sarà anche indicato come
doppio lato. I dischi a lato singolo sono utilizzati in alcuni sistemi di dischi meno costosi.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I dischi a piatti multipli impiegano una testina mobile con una testina di lettura-scrittura per ogni superficie 56
del piatto. Al centro del disco, tutte le testine hanno la stessa distanza e si muovono insieme perché tutte le
testine sono fissate meccanicamente. Nel piatto, un insieme di tutte le tracce nella stessa posizione relativa
è noto come cilindro.

Questo tipo di meccanismo è utilizzato soprattutto nei floppy disk. Questo tipo di disco è il meno costoso, è
piccolo e contiene anche un piatto flessibile. I gruppi di unità sigillati sono quasi privi di contaminanti e
contengono le testine Winchester. IBM utilizza il termine Winchester come nome in codice, ed è stato
utilizzato per il modello di disco 3340 prima del suo annuncio in IBM. Le workstation e i personal computer
contengono comunemente un disco incorporato, noto come disco Winchester. Questo disco viene anche
chiamato disco rigido.

In un sistema mobile, ci sarà un tempo di ricerca che può essere definito come il tempo necessario per
posizionare la testina sulla traccia. Ci sarà anche una latenza di rotazione o ritardo di rotazione, che può
essere definita come il tempo impiegato dall'inizio del settore per raggiungere la testina. Il tempo
necessario per raggiungere la posizione di scrittura o lettura è noto come tempo di accesso, pari alla
somma del ritardo di rotazione e dell'eventuale tempo di ricerca.
Una volta che la testina ha raggiunto la sua posizione, possiamo eseguire l'operazione di lettura o scrittura
mentre il settore si muove sotto la testina. Questo processo può essere chiamato la parte di trasferimento
dei dati dell'operazione e il tempo impiegato per trasferire i dati è noto come tempo di trasferimento.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Prestazionalmente parlando, quindi con relativa temporizzazione: 57

Dischi RAID

RAID è una tecnologia utilizzata per aumentare le prestazioni e/o l'affidabilità dell'archiviazione dei dati.
L'abbreviazione sta per Redundant Array of Independent Drives o Redundant Array of Inexpensive Disks,
più vecchio e meno utilizzato. Un sistema RAID è costituito da due o più unità che lavorano in parallelo.
Possono essere dischi rigidi, ma si sta diffondendo la tendenza a utilizzare questa tecnologia anche per le
unità SSD (Solid State Drives). Esistono diversi livelli RAID, ciascuno ottimizzato per una situazione specifica.
Questi non sono standardizzati da un gruppo industriale o da un comitato di standardizzazione. Questo
spiega perché a volte le aziende propongono numeri e implementazioni uniche.

- RAID 0

Il RAID 0 può essere chiamato anche striping del


disco. Nella tecnica RAID 0, i dati vengono suddivisi in
modo uniforme su due o più dispositivi di
archiviazione come HDD o SDD. In questa tecnica, i
dati vengono organizzati in modo tale che gli utenti
possano leggere o scrivere i file più velocemente.
Grazie a questo processo, le prestazioni si
velocizzano. Se si dispone di un gran numero di
applicazioni e di dati enormi, la soluzione migliore è
lo stripping del disco.

La configurazione di RAID 0 è molto semplice. Può


anche essere definito il tipo più conveniente di
organizzazione ridondante dei dischi. Tuttavia,
questo tipo di organizzazione non è in gradodi gestire
i guasti o gli errori e non può essere utilizzato per
gestire i dati critici. Questo perché scrive il primo
blocco nel primo disco, il secondo nel
disco successivo e così via. Questo processo viene ripetuto fino a raggiungere tutti i dischi. Infine, torna al

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

primo disco. Ciò significa che tutti i dischi lavorano in parallelo e che siamo in grado di vedere tutte le 58
prestazioni dei nostri dischi.
Il rovescio della medaglia è che non c'è ridondanza e quindi se un disco si rompe, perdiamo tutti i dati su
tutti i dischi. Quindi RAID 0 offre prestazioni elevate ed espansione dello storage, ma in realtà è meno
affidabile rispetto a un singolo disco.

Vantaggi del RAID 0


o Nelle operazioni di lettura e scrittura, offre grandi prestazioni.
o Non ci sarà alcun overhead perché RAID 0 utilizza tutta la capacità di archiviazione.
o Con RAID 0 è possibile implementare facilmente la tecnologia.
Svantaggi del RAID 0
o Il RAID 0 non può essere utilizzato nei sistemi critici perché non è in grado di tollerare i guasti.
o Se un disco si guasta in RAID 0, anche tutti i dati degli altri dischi vanno persi.

- RAID 1

RAID 1 può essere chiamato anche Mirroring.


Prende tutti i dati da un disco e li scrive su un
secondo disco, che è parallelo al primo. In RAID
1, la ridondanza è molto elevata perché ogni
disco contiene la copia esatta dei dati presenti
su un altro disco. Per funzionare ha bisogno di
almeno due dischi. La configurazione di RAID 1
fornisce una protezione contro la perdita di
dati, o possiamo dire che ha una capacità di
tolleranza ai guasti. Se un disco si guasta, la
copia di quel disco fornisce i dati necessari.
In questo caso, i sistemi possono leggere i dati
da entrambi i dischi contemporaneamente.
Grazie a questa caratteristica, il sistema è in
grado di accelerare le prestazioni e la
disponibilità. Tuttavia, le prestazioni
dell'operazione di scrittura sono inalterate.

Richiede più tempo rispetto all'operazione di lettura perché il RAID 1 contiene due dischi che scrivono in
parallelo e l'operazione di scrittura utilizza la capacità di un disco e deve scrivere gli stessi dati due volte. In
RAID 1, lo svantaggio dei dischi è rappresentato dai costi elevati, perché un disco deve costruire il doppio
della capacità effettivamente necessaria a questo livello.

Vantaggi del RAID 1


- Rispetto al disco singolo, il RAID 1 offre un'eccellente velocità di lettura e scrittura.
- Ha la capacità di tolleranza ai guasti. Se un disco si guasta, non è necessario ricostruire i dati e basta
copiare i dati nel disco sostitutivo.
- È una tecnologia molto semplice e anche l'implementazione del RAID 1 è molto semplice.

Svantaggi del RAID 1

- Nel RAID 1, i dati devono essere scritti due volte. Per questo motivo, la capacità di archiviazione
effettiva è solo la metà della capacità totale del disco, e questo è il principale svantaggio del RAID 1.
- Il RAID 1 è più costoso rispetto al RAID 0 perché richiede due dischi per il mirroring dei dati.
- Il software RAID 1 non consente sempre la sostituzione a caldo dei dischi guasti. Quando si spegne
il computer attraverso il quale è stato attaccato il disco guasto, quest'ultimo può essere solo
sostituito.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Molte persone utilizzano contemporaneamente i server e questo processo di spegnimento 59


potrebbe non essere accettato. Per questo motivo, questi tipi di sistemi utilizzano in genere
controller hardware che supportano la sostituzione a caldo dei dischi.

RAID 2
Il RAID 2 può essere chiamato anche striping a livello di bit. In RAID 2, si effettua lo striping dei bit sui dischi
anziché lo striping dei blocchi sui dischi. A questo livello, sono necessari due gruppi di dischi. Il primo
gruppo di dischi verrà utilizzato per scrivere i dati, mentre il secondo gruppo di dischi verrà utilizzato per
scrivere i codici di correzione degli errori.
In questo livello, utilizzeremo il codice di correzione degli errori di Hamming (ECC) e poi useremo i dischi di
ridondanza per memorizzare le informazioni del codice ECC. Il codice di Hamming è un tipo di codice di
correzione degli errori lineare, in grado di rilevare fino a (d - 1) errori di bit e di correggere (d -1)/2 errori di
bit. Dove d è un tipo di parola di codice dato dalla minima distanza di Hamming tra tutte le coppie. Se d è
maggiore o uguale alla distanza di Hamming tra il modello di bit trasmesso e quello ricevuto, solo allora
sarà possibile una comunicazione affidabile. Al contrario, un semplice codice di parità è in grado di rilevare
solo un numero dispari di errori e non può correggere l'errore.
Quando scriviamo i dati sui dischi, il codice ECC (codice di correzione degli errori) per i dati viene valutato al
volo. Successivamente, i bit dei dati vengono spogliati sui dischi di dati e, infine, il codice ECC viene scritto
sui dischi di ridondanza. Quando si leggono i dati dai dischi, si utilizzano i dischi di ridondanza per leggere il
codice ECC corrispondente. A questo punto verifica se i dati sono coerenti. Se necessario, esegue le
correzioni appropriate al volo.
Questo processo utilizza molti dischi. Verrà configurato in varie configurazioni di dischi. Ora il RAID 2 non è
più utile perché è costoso e l'implementazione del RAID 2 nel controller RAID è difficile. Ora anche l'ECC è
ridondante perché i dischi rigidi sono in grado di svolgere da soli il lavoro dell'ECC.

Vantaggi di RAID 2

o Il RAID 2 utilizza il codice Hamming per la correzione degli errori.


o Può memorizzare la parità con l'aiuto di un'unità designata.

Svantaggi del RAID 2


o Il RAID 2 necessita di un'unità aggiuntiva per il rilevamento degli errori.
o Contiene un'unità aggiuntiva. Per questo motivo è costoso e ha una struttura complessa.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

RAID 3 60
Il RAID 3 può essere chiamato anche Byte level stripping. Il funzionamento di RAID 3 è identico a quello di
RAID 0, in quanto utilizza lo stripping a livello di byte, ma necessita di un disco aggiuntivo nell'array. Il RAID
3 è utilizzato per supportare un tipo speciale di processore nei calcoli del codice di parità, che può essere
chiamato "disco di parità". In RAID 3, si esegue lo striping dei byte sui dischi anziché lo striping dei blocchi
sui dischi. A questo livello, sono necessari più dischi di dati e un disco dedicato per memorizzare la parità.
Nel processo di configurazione di RAID 3, i dati vengono suddivisi in singoli byte e quindi salvati su un disco.
Per ogni riga di dati, viene determinato il disco di parità e quindi viene salvato nel disco di parità indicato. In
caso di guasto, il sistema è in grado di recuperare i dati con l'aiuto dei byte di parità corrispondenti e con il
calcolo appropriato dei byte rimanenti.

Sebbene questo livello sia raramente utilizzato nella pratica, presenta numerosi vantaggi: in primo luogo, è
in grado di resistere in caso di danneggiamento del disco durante l'installazione. In secondo luogo, ha una
velocità di lettura molto elevata. Purtroppo, il RAID 3 presenta anche molti svantaggi. In primo luogo,
rispetto alla velocità di lettura, la velocità di scrittura è molto lenta a causa della necessità di calcolare il
checksum. (Anche i controller hardware RAID non sono in grado di risolvere questo problema). Il secondo
problema è che in caso di guasto di un disco, l'intero sistema funzionerà molto lentamente. Il RAID 3 ha la
capacità di resistere ai guasti, il che significa che se un disco dell'array si guasta, sostituirà il disco
danneggiato, ma il processo di sostituzione è molto costoso. Il terzo problema è che il disco viene utilizzato
per calcolare le checksum, il che rappresenta il collo di bottiglia delle prestazioni dell'intero array.
Nonostante la descrizione di cui sopra, RAID 3 non è in grado di mostrare una soluzione valida, affidabile ed
economica. Per questo motivo il RAID 3 viene utilizzato raramente nella pratica. I sistemi basati su RAID 3
sono utilizzati per lo più per scopi di implementazione in cui file molto grandi sono riferiti da un numero
ridotto di utenti.

Vantaggi del RAID 3


- Il RAID 3 offre un'elevata velocità di trasferimento dei dati di grandi dimensioni.
- Risolve il principale svantaggio del RAID 2, ossia la resistenza ai guasti e ai guasti del disco.

Svantaggi del RAID 3


- Se si deve trasferire solo un file di piccole dimensioni, la configurazione potrebbe essere eccessiva.
- Se si verifica un guasto del disco, la velocità di trasferimento diminuisce in modo significativo.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

RAID 4 61
Il RAID 4 è noto come striping a livello di blocco. Il funzionamento di RAID 4 è identico a quello di RAID 3. La
differenza principale è il processo di condivisione dei dati. I dati vengono suddivisi in blocchi da 16, 32, 64 o
128 GB. Come il RAID 0, i dati vengono scritti sul disco. Per ogni riga di dati scritti, viene utilizzato un disco
di parità per scrivere qualsiasi blocco registrato. Ciò significa che questo livello utilizza lo striping dei dati a
livello di blocco anziché a livello di byte. RAID 5 e RAID 4 hanno molte somiglianze, ma RAID 4 confina tutti i
dati di parità su un singolo disco. Si può quindi dire che non utilizza la parità distributiva.
In RAID 4 è possibile completare l'implementazione e la configurazione con l'aiuto di almeno tre dischi. Il
RAID 4 richiede anche un supporto hardware per eseguire i calcoli di parità. Per questo motivo, siamo in
grado di recuperare i dati con l'aiuto di operazioni matematiche appropriate.

Vantaggi del RAID 4


- RAID 4 consente lo striping a livello di blocco, che permette di inviare simultaneamente le richieste di I/O.
- Fornisce un basso overhead di archiviazione. Se si aggiungono vari dischi, l'overhead diventa più basso.
- Questo livello non necessita di un controller sincronizzato o di mandrini.

Svantaggi del RAID 4


- Contiene le unità di parità, il che può portare a un collo di bottiglia.
- Se si cerca di eseguire un'operazione di scrittura simultanea, l'operazione sarà più lenta perché le
informazioni di parità vengono scritte su un solo disco.

RAID 5

RAID 5 può essere chiamato Stripping con parità. Utilizza il livello di blocco per lo striping dei dati e utilizza
anche la parità distributiva. Il RAID 5 richiede un minimo di tre dischi, ma può funzionare fino a 16 dischi. È
il livello RAID più sicuro. La parità è un tipo di dati binari grezzi. Il sistema RAID calcola i valori di parità e,
utilizzando questi valori, crea un blocco di parità. Se un disco si guasta nel sistema RAID, il blocco di parità
viene utilizzato per recuperare i dati a strisce. La maggior parte dei sistemi RAID con funzione di parità
utilizza l'array per memorizzare i blocchi di parità nei dischi. A questo livello, i blocchi di dati sono suddivisi
in strisce tra le unità. La somma di controllo di parità di tutti i blocchi di dati viene scritta solo su un'unità.
La somma di controllo di parità non utilizza un'unità fissa, ma viene distribuita su tutte le unità. Se i dati di
un blocco di dati non sono più disponibili, con l'aiuto dei dati di parità il computer può ricalcolare i dati. Ciò
significa che in caso di guasto di una singola unità, il RAID 5 è in grado di resistere al guasto di qualsiasi
disco dell'array senza accedere ai dati o perderli.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Anche se è possibile utilizzare RAID 5 nel software, il controller consigliato è quello hardware. Questi 62
controller possono migliorare le prestazioni di scrittura utilizzando spesso la memoria cache extra. In
questo livello, le prestazioni del RAID 0 sono combinate con la ridondanza del RAID 1, ma questo processo
richiede un'enorme quantità di spazio di archiviazione, che può essere circa un terzo della capacità
utilizzabile. Nell'array, tutte le unità servono per le richieste di scrittura simultaneamente. Ecco perché
questo livello aumenta le prestazioni di scrittura. Tuttavia, l'implicazione della scrittura può influire sulle
prestazioni dell'intero disco, poiché è necessario eseguire più passaggi e ricalcoli se si apportano piccole
modifiche alle strisce.
In breve, possiamo dire che RAID 5 offre affidabilità e prestazioni elevate. Ha la capacità di bilanciare le
letture e le scritture ed è anche sicuro. RAID 5 memorizza la parità utilizzando lo spazio dell'intero disco e
riduce anche la quantità aggregata di dati che gli utenti possono salvare. RAID 5 è un tipo di sistema
eccellente a tutto tondo, che viene utilizzato per fornire prestazioni decenti e combinare un'archiviazione
efficiente con un'eccellente sicurezza. È utilizzato principalmente per i server di file e applicazioni che
contengono un numero limitato di unità di dati.

Vantaggi del RAID 5


- In RAID 5, le transazioni di scrittura dei dati sono lente a causa del calcolo della parità, mentre le
transazioni di lettura dei dati sono molto veloci.
- In caso di guasto di un disco nel RAID 5, è ancora possibile accedere a tutti i dati, anche se il disco guasto
viene sostituito e i dati vengono ricostruiti dal controller di archiviazione su un nuovo disco.

Svantaggi del RAID 5


- Il guasto di un disco influisce sul throughput, ma il processo è ancora accettabile.
- RAID 5 è una tecnologia complessa. Supponiamo che un disco da 4 TB nell'array di vari dischi si guasti. In
questo caso, la sostituzione e il ripristino dei dati del disco guasto possono richiedere un giorno o più, in
base alla velocità del controller e al carico dell'array. A questo punto, se un disco si guasta, i dati saranno
persi per sempre.

RAID 6

Il RAID 6 può anche essere chiamato Striping con doppia parità. Il funzionamento del RAID 5 è identico a
quello del RAID 6, con la differenza che nel RAID 6 il sistema memorizza un blocco di parità aggiuntivo su
ciascun banco. Per questo motivo, viene attivata una configurazione in cui prima che l'array non sia
disponibile, i due dischi possono essere guasti. Ha bisogno di due set diversi per i calcoli di parità e ha la
capacità di ricostruire un array anche se due unità si guastano contemporaneamente. RAID 6 necessita di
un minimo di quattro dischi e può sopportare due dischi che si guastano contemporaneamente. I due dischi
saranno utilizzati per i dati, mentre i due dischi rimanenti saranno utilizzati per le informazioni di parità. Se

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

il numero di dischi aumenta, aumentano le possibilità di guasti multipli e la complessità della ricostruzione 63
del set di dischi.
Rispetto al RAID 5, offre una ridondanza maggiore e aumenta anche le prestazioni di lettura. In caso di
operazioni di scrittura intensive, anche questo livello soffrirà dello stesso overhead di prestazioni del server.
Le prestazioni dipendono dall'architettura del sistema RAID, cioè dal software o dall'hardware. Se il sistema
esegue il calcolo della parità ad alte prestazioni con l'aiuto di un software di elaborazione incluso, e se si
trova nel firmware, le prestazioni ne risentiranno.
In RAID 6, le possibilità che due dischi si guastino contemporaneamente sono molto ridotte. Nel sistema
RAID 5, se un disco si guasta, ci vorranno ore, giorni o più per sostituirlo con un nuovo disco. A quel punto,
se un altro disco si guasta, perderemo tutti i nostri dati per sempre. Nel sistema RAID 6, invece, l'array RAID
sopravvive anche al secondo guasto.

Vantaggi del RAID 6


- In RAID 6, le transazioni di lettura dei dati sono molto veloci, proprio come in RAID 5.
- È più sicuro del RAID 5 perché se due dischi si guastano, siamo in grado di accedere a tutti i nostri
dati anche quando il sistema viene sostituito con i dischi guasti.

Svantaggi del RAID 6

- Nel RAID 6 è necessario calcolare la parità aggiuntiva. Per questo motivo, le transazioni di scrittura
dei dati nel RAID 6 sono più lente rispetto al RAID 5. Possono essere più lente del 20% rispetto al
RAID 5.
- Se si verifica un guasto del disco, il throughput ne risentirà, ma il processo è comunque accettabile.
- RAID 6 è una tecnologia complessa. In caso di guasto di un disco in un array RAID, la ricostruzione
dell'array può richiedere molto tempo.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Un paragone finale: 64

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

65

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

66

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

67

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

68

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

69

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

70

Dischi SSD (Solid State Drives)/Dischi a stato solido


Le unità a stato solido sono dispositivi di memorizzazione non volatili in grado di contenere grandi quantità
di dati. Utilizzano memorie flash NAND, che offrono il vantaggio di non avere parti meccaniche in
movimento e quindi un accesso immediato ai dati.
Sebbene le unità SSD svolgano la stessa funzione delle unità disco, i loro componenti interni sono molto
diversi. A differenza dei dischi rigidi, le unità SSD non hanno parti in movimento (per questo sono chiamate
unità allo stato solido). Invece di memorizzare i dati su piatti magnetici, le unità SSD li memorizzano
utilizzando la memoria flash. Poiché le unità SSD non hanno parti in movimento, non devono "girare"
durante lo stato di sospensione e non devono spostare la testina dell'unità in parti diverse dell'unità per
accedere ai dati. Pertanto, le unità SSD possono accedere ai dati più velocemente delle unità HDD.

Le unità SSD presentano anche altri vantaggi rispetto alle unità disco. Ad esempio, le prestazioni di lettura
di un disco rigido diminuiscono quando i dati vengono frammentati, ovvero suddivisi in più posizioni del
disco. Le prestazioni di lettura di un'unità SSD non diminuiscono in base alla posizione in cui i dati sono
memorizzati sul disco. Pertanto, la deframmentazione di un'unità SSD non è necessaria. Poiché le unità SSD
non memorizzano i dati in modo magnetico, non sono soggette a perdite di dati dovute a forti campi
magnetici in prossimità dell'unità. Inoltre, poiché le unità SSD non hanno parti in movimento, le possibilità
di guasti meccanici sono molto minori. Le unità SSD sono anche più leggere, più silenziose e consumano
meno energia rispetto alle unità disco. Per questo motivo le unità SSD sono diventate una scelta popolare
per i computer portatili.

Sebbene le unità SSD presentino molti vantaggi rispetto alle unità disco, hanno anche alcuni svantaggi.
Poiché la tecnologia delle unità SSD è molto più recente di quella dei dischi rigidi tradizionali, il prezzo delle
unità SSD è sostanzialmente più alto. All'inizio del 2011, le unità SSD costavano per gigabyte circa 10 volte
di più di un'unità disco. Pertanto, la maggior parte delle unità SSD vendute oggi ha una capacità molto
inferiore rispetto a quella di unità disco paragonabili. Inoltre, hanno un numero limitato di cicli di scrittura,
il che può causare un deterioramento delle prestazioni nel tempo. Fortunatamente, le unità SSD più recenti
hanno migliorato l'affidabilità e dovrebbero durare diversi anni prima che si noti una riduzione delle
prestazioni. Con il miglioramento della tecnologia SSD e il continuo calo dei prezzi, è probabile che le unità
allo stato solido comincino a sostituire i dischi rigidi per la maggior parte degli scopi.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

In particolare, essendo di tipo NAND: 71

Le unità SSD si basano su tecnologie di memoria flash che consentono di scrivere, leggere e cancellare i dati
più volte. La memoria flash è disponibile in due varianti: NOR e NAND. Sebbene ognuna di esse offra
vantaggi e svantaggi (una discussione che esula dallo scopo di questo articolo), la NAND è emersa come la
tecnologia preferita perché offre tempi di cancellazione e scrittura più rapidi. La maggior parte delle unità
SSD contemporanee si basa sulla tecnologia NAND flash, che è il motivo per cui è oggetto di questo articolo.

Un'unità SSD aziendale contiene più chip NAND flash per la memorizzazione dei dati. Ogni chip contiene
uno o più die e ogni die contiene uno o più piani. Un piano è diviso in blocchi e un blocco è diviso in pagine.
I blocchi e le pagine sono i più importanti, non perché si configurino o si manipolino direttamente, ma per il
modo in cui i dati vengono scritti, letti e cancellati su un chip NAND. I dati vengono letti e scritti a livello di
pagina, ma cancellati a livello di blocco, come illustrato nella Figura 1.

In questo caso, ogni pagina è di 4 kibibyte (KiB) e ogni blocco è di 256 KiB, il che equivale a 64 pagine per
blocco. (Un kibibyte è pari a 1024 byte. I kibibyte vengono talvolta utilizzati al posto dei kilobyte perché
sono più precisi. Un kilobyte può corrispondere a 1000 byte o a 1024 byte, a seconda dell'uso che se ne fa).
Ogni volta che l'unità SSD legge o scrive dati, lo fa in pezzi da 4-KiB, ma ogni volta che l'unità cancella dati,
esegue un'operazione da 256-KiB. Questa differenza di scrittura/cancellazione ha serie conseguenze
quando si aggiornano i dati, come si vedrà più avanti nell'articolo.

All'interno della cella NAND

Una pagina è composta da più celle che contengono ciascuna uno o più bit di dati. Un bit di dati è
rappresentato da uno stato di carica elettrica, determinato dagli elettroni intrappolati tra gli strati isolanti
della cella. Ogni bit viene registrato come carico (0) o non carico (1), fornendo la formula binaria necessaria
per rappresentare i dati.
Gli attuali chip NAND flash utilizzano celle a gate flottante o celle a trappola di carica. Fino a poco tempo fa
la maggior parte delle memorie NAND si basava su tecnologie a gate flottante, in cui gli elettroni sono
intrappolati tra due strati di ossido in una regione chiamata gate flottante. Lo strato di ossido inferiore è
abbastanza sottile da consentire il passaggio degli elettroni quando viene applicata una tensione al
substrato sottostante. Gli elettroni entrano nel floating gate durante un'operazione di scrittura ed escono
dal floating gate durante un'operazione di cancellazione.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il problema dell'approccio a gate flottante è che ogni volta che viene applicata la tensione e gli elettroni 72
passano attraverso lo strato di ossido, quest'ultimo si degrada leggermente. Più sono le operazioni di
scrittura e cancellazione, maggiore è il degrado, fino a quando la cella potrebbe non essere più utilizzabile.
Si tenga presente, tuttavia, che le tecnologie delle unità SSD hanno fatto passi da gigante, rendendole più
affidabili e durevoli, oltre che in grado di fornire maggiori prestazioni e memorizzare più dati. Allo stesso
tempo, il loro prezzo continua a scendere, rendendole molto più competitive.

I produttori continuano a esplorare nuove tecnologie per migliorare le unità SSD. Ad esempio, molti
produttori stanno adottando tecnologie a trappola di carica per le loro celle NAND. Le celle a trappola di
carica sono simili alle celle a gate flottante, ma utilizzano materiali isolanti e metodologie diverse per
intrappolare gli elettroni, ottenendo celle meno soggette a usura. Tuttavia, le tecnologie a trappola di
carica comportano problemi di affidabilità, per cui nessuno dei due approcci è ideale.

Naturalmente le tecnologie floating gate e charge gate sono molto più complesse, ma questo dovrebbe
darvi un'idea di cosa sta succedendo, nel caso in cui vi imbattiate in questi termini. Ma sappiate anche che
le tecnologie dei gate sono solo una parte dell'equazione quando si tratta di capire la struttura delle celle
NAND.
In effetti, la preoccupazione maggiore quando si valutano le unità SSD è il numero di bit memorizzati in ogni
cella. Le attuali unità SSD accettano da uno a quattro bit per cella, con un numero correlato di stati di carica
per cella, come mostrato nella tabella seguente. Si noti che i produttori stanno lavorando anche su flash
con celle a cinque bit, denominate penta-level cell (PLC), ma la giuria non è ancora convinta di questa
tecnologia.

Dischi SSD: vantaggi


- Operazioni di I/O ad alte prestazioni al secondo (IOPS): aumenta notevolmente le prestazioni dei
sottosistemi di I/O
- Durata: meno suscettibile a urti e vibrazioni
- Maggiore durata: gli SSD non sono soggetti a usura meccanica
- Consumo energetico inferiore: gli SSD consumano molta meno energia rispetto agli HDD di
dimensioni comparabili
- Funzionalità più silenziose e più fredde: meno spazio richiesto, costi energetici inferiori e più
ecologici
- Tempi di accesso e tassi di latenza inferiori: oltre 10 volte più veloci dei dischi rotanti in un HDD

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

73

I dischi SSD hanno due problemi:


- performance che decadono con l’uso
o file memorizzati in pagine di 4KB, tipicamente non in pagine contigue
o grandezza del blocco della memoria flash: 512 KB (128 pagine)
o scrittura in una pagina:
1. l'intero blocco che contiene la pagina deve essere letto dalla memoria flash e
inserito in un buffer RAM, dove la pagina è aggiornata
2. prima che il blocco possa essere riscritto nella memoria flash, è necessario
cancellare l'intero blocco della memoria flash
3. l'intero blocco dal buffer viene riscritto nella memoria flash
o con l’uso i file si frammentano (pagine memorizzate su blocchi diversi) e le prestazioni
decadono
Soluzioni:
- over-provisioning (non è altro che uno spazio del disco SSD non allocato, funzionale a garantire un
numero adeguato di celle sostituibili a quelle che raggiungono il limite del ciclo di programmazione
e cancellazione, così da prolungare la vita dello stesso SSD, cancellazione pagine inattive)
- comando TRIM (Il comando SSD TRIM contrassegna semplicemente i dati non validi e indica
all'unità SSD di ignorarli durante il processo di garbage collection. L'SSD deve quindi spostare meno
pagine durante la garbage collection, riducendo così il numero totale di cicli di
programmazione/cancellazione (cicli P/E) del supporto NAND flash e prolungando la durata
dell'SSD)

- Numero limitato di scritture: intorno a 100.000 scritture

Soluzioni:
- cache front-ending (tenere copie dei metadati e dei dati stessi, tali da poterli mantenere in locale)
- distribuzione scritture
- gestione blocchi esauriti, RAID, stima lunghezza vita blocchi

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

74

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

75

Memorie esterne: CD-ROM


Il CD-ROM (Compact disc read-only memory) è un dispositivo di memorizzazione che può essere letto ma
non scritto.
Il CD-ROM è stata una convenzione comune per la distribuzione di audio e altri dati nel corso degli anni,
prima che le piccole unità flash a stato solido e altri dispositivi iniziassero a prendere il sopravvento.

Così come il nastro magnetico aveva sostituito il vinile, il compact disc ha sostituito il nastro magnetico
come mezzo durevole e semplice per memorizzare le informazioni.
Per molti versi, il CD-ROM è stato l'ultimo metodo di archiviazione fisica dei dati, coincidente con l'uso dei
floppy disk per i computer. Al contrario, oggi l'archiviazione e la trasmissione dei dati sono per lo più
"completamente digitali", nel senso che piccoli pezzi di hardware possono gestire le informazioni che
sarebbero state inserite in decine di singoli compact disc o floppy disk.

Poiché i compact disc sono diventati un formato di dati comune sia per la musica che per altri tipi di dati, i
CD scrivibili consentono agli utenti di scaricare i dati dai loro computer per utilizzarli in altri dispositivi, ad
esempio per replicare le canzoni e le playlist da utilizzare negli impianti stereo dotati di funzionalità CD.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

76
Quando i compact disc sono diventati utili per memorizzare e distribuire software oltre alla musica, le
aziende hanno lavorato su protocolli tecnici specifici per i diversi tipi di dati digitali scritti sui prodotti CD-
ROM. Questi protocolli continuano ad aiutare a gestire video, singoli file e diversi tipi di dati che possono
essere presenti su un compact disc.

Caratteristiche principali

- Concepiti originariamente per dati audio


- 650 MB memorizzano più di 70 minuti audio
- Dischi di policarbonato rivestiti con materiale altamente riflettente (di solito alluminio)
- Dati memorizzati come microscopici pozzetti (pit)
- Lettura tramite laser
- Densità di memorizzazione costante
- Velocità lineare costante

Questi passaggi riguardano la lettura di un CD-ROM:


- Una singola traccia scorre a spirale dal centro del disco verso l'esterno. La traccia è costituita da
terre e buche che rappresentano gli uni e gli zeri dei dati binari.
- Un laser a bassa potenza viene puntato su una superficie metallica e la riflessione viene catturata
da un sensore a fotodiodo; le terre si riflettono in modo diverso rispetto ai pit, il che significa che è
in grado di distinguere uno 0 e un 1.
- Il disco gira e i laser seguono la traccia.
- I dati binari vengono messi insieme e il CD-ROM viene letto.

Velocità lettore CD-ROM


- Audio: singola velocità
o Velocità lineare costante
- 1.2 ms-1
- Traccia (a spirale) lunga 5.27 km
- memorizza 4391 secondi = 73.2 minuti
- Altre velocità sono riferite come multipli
- Per esempio: 24x
- La velocità dichiarata è quella massima che il lettore può raggiungere

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Formato dati CD-ROM 77

Con riferimento ad un tipo di CD-ROM, chiamati Yellowbook, per spiegare le singole modalità:

Accesso casuale su CD-ROM


- Difficile a causa della velocità lineare costante
- Spostare la testina in posizione approssimata
- Configurare la giusta velocità di rotazione
- Leggere l’indirizzo
- Altri aggiustamenti per spostarsi sul settore richiesto

Pro e contro CD-ROM


- Capacità (?, ormai non più…)
- Facili da produrre su grande scala
- Rimovibile
- Robusto
- Costoso per piccole quantità
- Lento
- Solo lettura

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Esistono altri formati di CD: 78


- Un Compact Disc Recordable (CD-R) è un disco di tipo Write Once Read Multiple (WORM). Questi
dischi possono registrare solo una volta i dati, che diventano permanenti sul disco. Non è possibile
registrare altri dati. Può quindi essere letto come un CD-ROM standard. Dopo la scrittura su un CD-
R, il disco diventa un CD-ROM.
- Un Compact disc Re-Writable (CD-RW) è un disco cancellabile che può essere riutilizzato. I dati su
un disco CD-RW possono essere cancellati e registrati in più riprese.

Similmente, abbiamo anche i DVD (Digital Video Disk, per riprodurre film) o Digital Versatile Disk (lettore
dati e video per computer).

I DVD hanno lo stesso diametro e spessore dei CD e sono realizzati con alcuni degli stessi materiali e metodi
di produzione. Come i CD, i dati su un DVD sono codificati sotto forma di piccoli fori e protuberanze nella
traccia del disco.
Un DVD è composto da diversi strati di plastica, per un totale di circa 1,2 millimetri di spessore. Ogni strato
è creato mediante stampaggio a iniezione di policarbonato. Questo processo forma un disco con
microscopiche protuberanze disposte come un'unica, continua e lunghissima traccia a spirale di dati. Per
saperne di più sulle protuberanze, si veda più avanti.

Una volta formati i pezzi trasparenti di policarbonato, un sottile strato riflettente viene spruzzato sul disco,
coprendo le protuberanze. Per gli strati interni si usa l'alluminio, mentre per gli strati esterni si usa uno
strato d'oro semi-riflettente, che permette al laser di focalizzarsi attraverso gli strati esterni e su quelli
interni. Dopo aver realizzato tutti gli strati, ciascuno di essi viene rivestito di lacca, compresso e
polimerizzato sotto la luce infrarossa. Per i dischi monofacciali, l'etichetta viene serigrafata sul lato non
leggibile. I dischi a doppia faccia sono stampati solo sull'area non leggibile vicino al foro centrale.
Ogni strato scrivibile di un DVD ha una traccia di dati a spirale. Nei DVD a singolo strato, la traccia gira
sempre dall'interno del disco verso l'esterno. Il fatto che la traccia a spirale inizi al centro significa che un
DVD a singolo strato può essere più piccolo di 12 centimetri, se lo si desidera.

I vari strati riflettenti, a seconda


delle loro proprietà, riescono a
trasmettere meglio la luce
incrementando e migliorando la
memorizzazione.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Quello che l'immagine a sinistra non riesce 79


a far capire è quanto sia incredibilmente
piccola la traccia dei dati: solo 740
nanometri separano una traccia dall'altra
(un nanometro è un miliardesimo di
metro). Le protuberanze allungate che
compongono la traccia sono larghe 320
nanometri ciascuna, lunghe almeno 400
nanometri e alte 120 nanometri. La figura
seguente illustra come osservare le
protuberanze attraverso lo strato di
policarbonato.
Spesso si legge di "buche" su un DVD
anziché di protuberanze. Sul lato
dell'alluminio appaiono come pozzetti, ma
sul lato da cui il laser legge sono
protuberanze.

Le dimensioni microscopiche delle protuberanze rendono la traccia a spirale di un DVD estremamente


lunga. Se si potesse sollevare la traccia dati da un singolo strato di un DVD e allungarla in linea retta,
sarebbe lunga quasi 7,5 miglia! Ciò significa che un DVD a doppio lato e doppio strato conterrebbe 30 miglia
(48 km) di dati!

Infine, il nastro magnetico.


Esso è un nastro di plastica con rivestimento magnetico. È un supporto di memorizzazione su una grande
bobina aperta o in una cartuccia o cassetta più piccola (come una cassetta musicale). I nastri magnetici
sono supporti di memorizzazione più economici. Sono durevoli, possono essere scritti, cancellati e riscritti.
Data la loro grande lentezza, sono usati principalmente per backup di dati.
Sebbene sia ottimo per un uso a breve termine, il nastro magnetico è altamente incline alla disintegrazione.
A seconda dell'ambiente, questo processo può iniziare dopo 10-20 anni.

Con il passare del tempo, i nastri magnetici prodotti negli anni '70 e '80 possono soffrire di un tipo di
deterioramento chiamato "sindrome della macchia appiccicosa". È causata dall'idrolisi del legante del
nastro e può rendere il nastro inutilizzabile.

Come funzionano

I nastri magnetici convertono i segnali audio


elettrici in energia magnetica, costituendo così
la base del loro principio di funzionamento. La
conversione imprime tali segnali sul nastro;
quando il nastro si sposta sulle testine
magnetiche, le particelle magnetiche fanno sì
che gli impulsi si allineino in schemi, provocando
la produzione del suono.
Il nastro viene spostato a una velocità costante
grazie a una macchina a nastro. Se la velocità
cambia per qualsiasi motivo, che si tratti di
motori difettosi o di impostazioni non corrette, i
dati potrebbero corrompersi. In generale, ha
una direzione di scorrimento a serpentina, tale
da salvare i dati simultaneamente su più tracce.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

80
Gestione I/O
Esistono molte periferiche da gestire con quantità di dati
differenti e a diverse velocità e formati. Normalmente i vari
dispositivi sono più lenti di CPU e RAM e si ha necessità di avere
moduli di I/O.

I moduli di ingresso/uscita (moduli I/O) fungono da mediatori


tra il processore e i dispositivi di ingresso/uscita. I moduli di
ingresso ricevono i segnali dagli interruttori o dai sensori e li
inviano al processore, mentre i moduli di uscita riportano i
segnali del processore ai dispositivi di controllo, come i relè o
gli avviatori di motori.
Un modulo di I/O svolge un ruolo fondamentale nel colmare il
divario tra un sistema informatico e i dispositivi esterni. Può
svolgere diverse funzioni, tra cui:
• Comunicazione con i dispositivi: Un modulo I/O può
svolgere diverse funzioni di comunicazione con i
dispositivi, come la segnalazione dello stato, i comandi
e il trasferimento di informazioni.
• Interfaccia diretta con CPU/Memoria e periferiche
• Controllo e temporizzazione: Per gestire correttamente il flusso di informazioni tra un sistema
informatico e un dispositivo esterno, un modulo I/O utilizza le risorse interne di un computer per
eseguire la gestione del tempo.
• Comunicazione con il processore: Per completare la comunicazione con il processore è necessario
che il modulo I/O svolga dei compiti, tra cui la decodifica e l'accettazione dei comandi, la
segnalazione degli aggiornamenti di stato e il riconoscimento del proprio indirizzo.
• Rilevamento degli errori: Un modulo I/O può rilevare una serie di problemi diversi tra il suo sistema
e un dispositivo esterno. Ciò include errori meccanici, come l'inceppamento della carta in una
stampante, e problemi basati sui dati durante la trasmissione.
• Buffering dei dati: Una delle funzionalità più importanti di un modulo I/O è quella di gestire la
velocità di trasferimento tra la memoria, il processore e le altre periferiche collegate.
• I moduli I/O migliorano anche le capacità di più sistemi. Sono una parte necessaria di qualsiasi
sistema informatico che coinvolga un dispositivo esterno. Un modulo di ingresso può portare a un
lavoro più efficiente e preciso grazie alle sue capacità multifunzionali.

I vantaggi dei moduli I/O


Esistono diversi tipi di moduli I/O e tutti svolgono un ruolo necessario in qualsiasi sistema operativo
efficace. I moduli I/O possono essere utili in un controllore logico programmabile (PLC) e in altri sistemi
operativi perché possono:
• Ridurre le spese per l'hardware.
• Risparmiare spazio nell'armadio di controllo.
• Possono essere installati in remoto.
• Semplificare il cablaggio e la configurazione dei cavi.
• Risparmio evidente sull'hardware.
• Aumentare l'organizzazione

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

81
Similmente vi sono i vari dispositivi esterni,
ciascuno comprensibile all’uomo (video,
stampante, tastiera), comprensibili dalla
macchina (monitoraggio e controllo) di
comunicazione (modem/rete (NIC)).
Tutto ciò che può essere collegato a un
computer dall'esterno può essere considerato
un dispositivo esterno. Qualsiasi dispositivo
periferico non alloggiato all'interno dell'armadio
del computer. Monitor, tastiere, mouse e
stampanti sono intrinsecamente dispositivi
esterni; tuttavia, anche i drive, gli adattatori di
rete e i modem possono essere esterni.

Come si vede, hanno dei bit dati che vengono elaborati da un’apposita logica di controllo da moduli e
buffer elaboratori, andando poi a tradurre per ogni singolo dispositivo ed elaborando (buffering) i dati,
rilevando possibili errori e comunicando con la CPU e i singoli dispositivi.
In generale, i passi di I/O sono così descritti:
- CPU interroga il modulo I/O sullo stato del dispositivo connesso
- Il modulo I/O restituisce lo stato del dispositivo
- Se dispositivo pronto a trasmettere, CPU richiede il trasferimento dei dati, tramite comando a
modulo I/O
- Il modulo I/O ottiene una unità di dati dal dispositivo esterno
- Il modulo I/O trasferisce i dati alla CPU

Essi permettono di
nascondere/rivelare le proprietà
di un dispositivo alla CPU,
supportando dispositivi
singoli/multipli, controllando
funzioni del dispositivo (o
lasciandolo alla CPU) e,
naturalmente, adattarsi allo
specifico sistema operativo.

Esistono 3 tecniche di gestione dell’I/O:


1) I/O da programma (I/O programmed)
L'I/O programmabile è una tecnica di I/O diversa dall'I/O a interrupt e dall'accesso diretto alla
memoria (DMA). L'I/O programmato è il tipo più semplice di tecnica di I/O per lo scambio di dati o
qualsiasi tipo di comunicazione tra il processore e i dispositivi esterni. Con l'I/O programmato, i dati
vengono scambiati tra il processore e il modulo di I/O. Il processore esegue un programma che
fornisce un'informazione sul funzionamento del modulo. Il processore esegue un programma che
gli dà il controllo diretto delle operazioni di I/O, compreso il rilevamento dello stato del dispositivo,
l'invio di un comando di lettura o scrittura e il trasferimento dei dati. Quando il processore invia un

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

comando al modulo I/O, deve attendere che l'operazione di I/O sia 82


completata. Se il processore è più veloce del modulo di I/O, ciò comporta
uno spreco di tempo per il processore. Il funzionamento complessivo
dell'I/O programmato può essere riassunto come segue:
- Il processore sta eseguendo un programma e incontra un'istruzione
relativa a un'operazione di I/O. Il processore esegue l'istruzione.
- Il processore esegue l'istruzione emettendo un comando al modulo di I/O
appropriato.
- Il modulo di I/O esegue l'azione richiesta in base al comando di I/O
impartito dal processore (READ/WRITE) e imposta i bit appropriati nel
registro di stato dell'I/O. Il processore controlla periodicamente lo stato
del modulo.
- Il processore controlla periodicamente lo stato del modulo di I/O fino a
quando non constata che l'operazione è stata completata (sprecando
tempo di CPU, dato che la stessa deve aspettare la fine dell’operazione da
parte dei moduli di I/O).

Nel dettaglio:
- CPU richiede operazione I/O
- Modulo I/O esegue operazione
- Modulo I/O setta bit di stato
- CPU controlla bit di stato periodicamente
- Modulo I/O non informa direttamente CPU
- Modulo I/O non interrompe CPU
- CPU può attendere o fare altro e controllare più tardi

La CPU, a sua volta, a ha una serie di comandi:


- CPU invia indirizzo
a. che identifica modulo (& dispositivo se >1 per modulo)
- CPU invia commando
- di controllo – dire al modulo cosa fare
a. ad esempio, dare velocità al disco
- di test – controlla lo stato
a. ad esempio, alimentazione? errore?
- di lettura/scrittura
a. il modulo trasferisce i dati tramite buffer dal/verso il dispositivo

Nell’I/O da programma il trasferimento dati è molto simile all’accesso alla memoria (dal punto di vista della
CPU). Ad ogni dispositivo viene assegnato un identificatore unico ed i comandi di CPU riferiscono tale
identificatore (indirizzo).
Il mapping I/O è fatto in due modi:
1) I/O memory-mapped, esiste un unico spazio di indirizzi per le locazioni di memoria e i dispositivi di
I/O e il processore tratta i registri di stato e di dati dei moduli di I/O come locazioni di memoria e
utilizza le stesse istruzioni macchina per accedere sia alla memoria che ai dispositivi di I/O. Quindi,
ad esempio, con 10 linee di indirizzo, è possibile supportare un totale di = 1024 locazioni di
memoria e indirizzi di I/O, in qualsiasi combinazione. Con l'I/O mappato in memoria, sul bus sono
necessarie una singola linea di lettura e una singola linea di scrittura.
2) I/O isolated, Con l'I/O isolato, il bus può essere dotato di linee di comando di lettura e scrittura
della memoria e di linee di comando di ingresso e uscita. Ora, la linea di comando specifica se
l'indirizzo si riferisce a una posizione di memoria o a un dispositivo di I/O. L'intera gamma di
indirizzi può essere disponibile per entrambi. L'intera gamma di indirizzi può essere disponibile per
entrambi. Ancora una volta, con 10 linee di indirizzo, il sistema può ora supportare sia 1024
locazioni di memoria che 1024 indirizzi di I/O.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Confronto tra I/O memory mapped e separato 83


La tecnica memory-mapped I/O ha diversi vantaggi
o Non necessita di istruzioni speciali
▪ Le istruzioni che accedono alla memoria “normale”
accedono anche alle aree di I/O
▪ Il software di controllo di dispositivo può essere
scritto interamente in linguaggi ad alto livello
- Consente una più agevole protezione
o è sufficiente nascondere le aree di I/O allo spazio di
indirizzamento dell’utente (privilegi)
- Con la tecnica della memoria segmentata, più aree
di I/O possono mappare sul medesimo spazio di
indirizzamento fisico

Tuttavia, anche alcuni svantaggi:


- Non si presta all’uso di cache
o Il dato rilevante è sempre e solo nella memoria del
dispositivo
o Occorre disabilitare selettivamente la cache
- Non è compatibile con architetture a bus multipli
o I dispositivi di I/O non possono rispondere ad
indirizzi emessi su bus non connessi
o Occorre filtrare gli indirizzi emessi dalla CPU ed
instradarli sul bus appropriato
▪ Filtraggio a sorgente piuttosto che a destinazione

Un interrupt I/O è un processo di trasferimento di dati in cui un dispositivo esterno o una periferica informa
la CPU di essere pronta per la comunicazione e richiede l'attenzione della CPU.

L'I/O guidato da interrupt è un approccio per trasferire dati tra la 'memoria' e i 'dispositivi di I/O' attraverso
il 'processore'. Le altre due tecniche sono l'I/O programmato e l'accesso diretto alla
memoria (DMA). L'I/O guidato da interrupt comporta l'uso di interrupt per lo
scambio di dati tra I/O e memoria.
Per migliorare le prestazioni del sistema si può utilizzare un approccio alternativo in
cui, dopo aver impartito il comando di I/O al modulo di I/O, il processore può
essere impegnato in altre operazioni. In questo modo, il tempo prezioso del
processore può essere utilizzato.

Funzionamento dell'I/O guidato da interrupt


In questa sezione studieremo come con l'approccio dell'I/O guidato da interrupt i
dati vengono scambiati tra la memoria e l'I/O attraverso il processore. Vedremo
l'intero scenario prima dal punto di vista del modulo I/O e poi dal punto di vista del
processore.
Consideriamo che i dati devono essere memorizzati nella memoria principale dal
modulo di I/O come input dal punto di vista del modulo di I/O.

1) A questo scopo, il processore invia un comando READ I/O al modulo I/O


corrispondente e procede con altre operazioni utili. Non attende che il
modulo I/O sia pronto con i dati desiderati.

2) Il modulo I/O elabora il comando READ I/O e legge i dati dalla periferica indirizzata. Il modulo I/O
memorizza i dati letti nel suo registro dati ed emette un segnale di interruzione al processore

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

attraverso la linea di controllo del bus di sistema. Inviando il segnale di interruzione, il modulo I/O 84
indica al processore che ora è pronto a trasmettere i dati. Tuttavia, il modulo I/O deve aspettare
che il processore richieda i dati al modulo I/O.

3) Quando il processore richiede i dati al modulo di I/O, li trasferisce sulla linea dati del bus di sistema.
Una volta che il modulo di I/O trasferisce i dati al processore, si predispone per un altro
trasferimento di I/O.

Discutiamo ora questo trasferimento di dati tra processore e I/O dal punto di vista del processore.

1) Per recuperare i dati dal modulo di I/O, il processore emette un comando READ e procede a fare
qualcos'altro. Ad esempio, inizia l'esecuzione di un altro programma, perché potrebbe lavorare su
più programmi alla volta.

2) Come sappiamo, ogni volta che il processore esegue un programma, dopo ogni ciclo di istruzioni
controlla se si sono verificati degli interrupt. Se trova un'interruzione in corso, risponde e serve
l'interruzione verificatasi.

3) Nel momento in cui il processore trova


un'interruzione da parte del modulo di I/O,
sospende l'esecuzione in corso e salva il contesto
(ad esempio, il contatore del programma, il
registro del processore) per servire l'interruzione.

4) A questo punto il processore richiede i dati al


modulo di I/O e accetta la parola di dati sulla linea
dati. Il processore salva questi dati nella memoria
e ripristina il contesto del programma su cui stava
lavorando e riprende l'esecuzione.

Le operazioni base, come da slide:


- CPU rilascia comando di lettura
- Modulo I/O ottiene i dati dalla periferica mentre la
CPU svolge altro lavoro
- Modulo I/O interrompe la CPU
- CPU richiede i dati al modulo I/O
- Modulo I/O trasferisce i dati alla CPU

La CPU, infatti, rilascia un comando di lettura e nel


frattempo esegue altro lavoro; controlla se c’è
interruzione alla fine di ogni ciclo di istruzione (ciclo
fetch/execute con trattamento delle interruzioni). Se
interruzione presente:
- Salva contesto (PC e registri)
- Interruzione del processo corrente ed elaborazione
interrupt
- Lettura dati da modulo I/O e scrittura in memoria

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Esiste inoltre il DMA (Direct Memory Access), che è una funzionalità fornita da alcune architetture di bus 85
per computer che consente di inviare dati direttamente da un dispositivo collegato (ad esempio un'unità
disco) alla memoria sulla scheda madre del computer. Il microprocessore non è coinvolto nel trasferimento
dei dati, accelerando così il funzionamento complessivo del computer.
Gli strumenti delle risorse di sistema di un computer sono utilizzati per la comunicazione tra hardware e
software. I quattro tipi di risorse di sistema sono:
- Indirizzi di I/O.
- Indirizzi di memoria.
- Numeri di richiesta di interruzione (IRQ).
- Canali di accesso diretto alla memoria (DMA).

I canali DMA sono utilizzati per comunicare i dati tra la


periferica e la memoria di sistema. Tutte e quattro le
risorse di sistema si basano su alcune linee del bus.
Alcune linee del bus sono utilizzate per gli IRQ, altre per
gli indirizzi (gli indirizzi di I/O e l'indirizzo della
memoria) e altre ancora per i canali DMA.
Un canale DMA consente a un dispositivo di trasferire
dati senza esporre la CPU a un sovraccarico di lavoro.
Senza i canali DMA, la CPU copia ogni dato utilizzando
un bus periferico dal dispositivo di I/O. L'utilizzo di un
bus periferico occupa la CPU. L'utilizzo di un bus
periferico occupa la CPU durante il processo di
lettura/scrittura e non consente di eseguire altre
operazioni fino al completamento dell'operazione.

Con il DMA, la CPU può eseguire altre operazioni mentre viene eseguito il trasferimento dei dati. Il
trasferimento dei dati viene innanzitutto avviato dalla CPU. Il blocco di dati può essere trasferito da e verso
la memoria dal DMAC in tre modi.
In modalità burst, il bus di sistema viene rilasciato solo al termine del trasferimento dei dati. In modalità
cycle stealing, durante il trasferimento dei dati tra il canale DMA e il dispositivo di I/O, il bus di sistema
viene ceduto per alcuni cicli di clock in modo che la CPU possa eseguire altre operazioni. Al termine del
trasferimento dei dati, la CPU riceve una richiesta di interrupt dal controller DMA. In modalità trasparente,
il DMAC può occupare il bus di sistema solo quando non è richiesto dal processore.

Tuttavia, l'uso di un controller DMA può causare problemi di coerenza della cache. I dati memorizzati nella
RAM a cui accede il controller DMA potrebbero non essere aggiornati con i dati corretti della cache se la
CPU utilizza una memoria esterna.
Le soluzioni comprendono il lavaggio delle linee della cache prima di avviare i trasferimenti DMA in uscita,
oppure l'esecuzione di un'invalidazione della cache sui trasferimenti DMA in entrata quando le scritture
esterne vengono segnalate al controller della cache.

Il controller DMA può accedere al canale:


- Una parola alla volta, sottraendo di tanto in tanto alla CPU il controllo sul canale (cycle stealing).
All’interno di questo:
o Il controllore DMA prende possesso del bus per un ciclo
o Trasferisce una parola (word) di dati
o Non è una interruzione (la CPU non cambia contesto)
o La CPU rimane “sospesa” proprio nel momento prima che acceda al bus
o Ad esempio, prima del caricamento di un dato e/o operando o di una scrittura
o Rallenta la CPU ma non così tanto come nel caso in cui sia la CPU stessa ad occuparsi del
trasferimento dati

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

86
- Per blocchi, prendendo possesso del canale per una serie di trasferimenti (burst mode)
- La CPU è bloccata in entrambi i casi, ma il burst mode è più efficace perché l’acquisizione del canale
è onerosa

L'interfaccia DMA trasferisce un


blocco completo di dati, una
parola alla volta, direttamente
alla o dalla memoria senza
passare per il processore. Al
termine del trasferimento,
l'interfaccia DMA trasmette un
segnale di interrupt al
processore. Quindi, in DMA il
coinvolgimento del processore
può essere limitato all'inizio e
alla fine del trasferimento,
come mostrato nella figura
precedente. Tuttavia, ci si
chiede quando il DMA debba
prendere il controllo del bus.

A questo proposito, ricordiamo il fenomeno dell'esecuzione di un'istruzione da parte del processore. La


figura seguente mostra i cinque cicli di esecuzione di un'istruzione. La figura mostra anche cinque punti in
cui è possibile rispondere a una richiesta DMA e un punto in cui è possibile rispondere a una richiesta di
interrupt. Si noti che una richiesta di interrupt viene riconosciuta solo in un punto di un ciclo di istruzioni,
ossia nel ciclo di interrupt.

Le configurazioni del DMA possono essere:


- A bus singolo, controller DMA isolato. Ogni trasferimento usa il bus due volte da I/O a DMA e poi da
DMA alla memoria. La CPU perde il possesso del bus due volte

- A bus singolo, controllore DMA integrato con I/O. Può controllare più di un dispositivo ed ogni
trasferimento usa il bus una volta da DMA a memoria. La CPU perde il controllo del bus una sola
volta.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Bus di I/O separato, DMA necessita di una sola interfaccia I/O. Ogni trasferimento usa il bus di 87
sistema una sola volta da DMA a memoria. La CPU perde il controllo del bus una sola volta

Esistono inoltre gli I/O Channels/Canali di I/O¸ che sono un’estensione del concetto di DMA.
Sono in grado di eseguire le istruzioni di I/O utilizzando un processore speciale sul canale di I/O e di
controllare completamente le operazioni di I/O. Il processore non esegue direttamente le istruzioni di I/O. Il
processore non esegue le istruzioni di I/O da solo. Il processore avvia il trasferimento di I/O ordinando al
canale di I/O di eseguire un programma in memoria.

Il programma specifica: dispositivo o dispositivi, area o aree di memoria, priorità e azioni in condizioni di
errore.
Tipi di canali di I/O :
1) Canale selettore:
Il canale selettore controlla più dispositivi ad alta velocità. È dedicato al trasferimento di dati con uno dei
dispositivi. Nel canale selettore, ogni dispositivo è gestito da un controllore o da un modulo di I/O. Il canale
selettore controlla i controllori di I/O mostrati nella figura.
2) Canale multiplexer :
Il canale multiplexer è un controller DMA che può gestire più dispositivi contemporaneamente. Può
eseguire trasferimenti a blocchi per più dispositivi contemporaneamente.

In questo canale vengono utilizzati due tipi di multiplexer:


1) Multiplexer di byte
È utilizzato per i dispositivi a bassa velocità. Trasmette o accetta caratteri. Intercalare i byte da diversi
dispositivi.
2) Multiplexer a blocchi
Accetta o trasmette blocchi di caratteri. Intercetta blocchi di byte da diversi dispositivi. Utilizzato per
dispositivi ad alta velocità.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

88
Esercizi sulla prima parte

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

89

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

90

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

91

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

92

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

93

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

94

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

95

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

96

Aritmetica del calcolatore


Come dicevamo, nella CPU esista la ALU, in
grado di eseguire le operazioni aritmetico-
logiche. Ogni altra componente nel calcolatore
serve questa unità, gestisce gli interi e riesce
anche a gestire i numeri reali (oltre che
operazioni logiche di controllo) .
La CPU richiede all'unità ALU di effettuare una
particolare operazione logico-matematica sui
dati. I dati ( input ) sono prelevati dai registri
del processore. L'operazione e i dati sono elaborati in linguaggio binario. Una volta elaborata l'operazione, il
risultato finale in output viene registrato nella locazione di memoria dell'unità aritmetico-logica, detta
accumulatore, o nei registri di uscita del processore e restituito all'unità di controllo.

Per la rappresentazione degli interi, possiamo solo usare 0 e 1 per rappresentare tutto. I numeri positivi
sono scritti in binario come sappiamo (es. 41 = 00101001). Non c’è bisogno del segno.

Per la rappresentazione in modulo e segno, si considera come segno il bit più a sinistra (0 positivo, 1
negativo). Ad esempio: +18 = 00010010 − 18 = 10010010
Problemi
- Per eseguire operazioni aritmetiche bisogna considerare sia i moduli che i segni
- Due rappresentazioni per lo 0: +0 𝑒 − 0

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

La rappresentazione in complemento a 2 è un tipo di rappresentazione in complemento dei numeri binari 97


che agevola e semplifica le operazioni aritmetiche nel sistema binario da parte del computer. La
rappresentazione in complemento a 2 si ottiene in modo simile alla rappresentazione in complemento
tradizionale a 1.
- Numeri positivi. Nel caso dei numeri binari positivi la rappresentazione in complemento a 2 è
uguale alla rappresentazione segno-grandezza. Vanno da 0 ad 2(𝑛−1) − 1
- Numeri negativi. Nel caso dei numeri binari negativi la rappresentazione in complemento a 2 è
uguale all'inversione di ogni cifra (bit) del numero binario in valore assoluto a cui viene addizionato
il numero binario uno (00000001)2. Il bit più significativo (a sinistra) è ad 1 ed i restanti 𝑛 − 1 bit
possono assumere 2(𝑛−1) configurazioni diverse

La seguente formula definisce il complemento a due:

- Bit più a sinistra è −2𝑛 − 1


- Per n bit: possiamo rappresentare tutti i numeri da −2(𝑛−1) a +2(𝑛−1)– 1
- Per i numeri positivi, come per modulo e segno 𝑛 zeri rappresentano lo 0, poi 1, 2, … in binario per
rappresentare 1, 2, … positivi
- Per i numeri negativi, da n uni per il -1, andando indietro

Vediamo ad esempio il complemento a due su 3/4 bit:

Confrontiamo le rappresentazioni di 𝑘 e – 𝑘
- da destra a sinistra, uguali fino al primo 1 incluso
- poi una il complemento dell’altra
Esempio (su 4 bit): 2 = 0010, −2 = 1110

In generale, su 8/16 bit, si rappresentano come numeri:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

La rappresentazione in complemento a 2 consente di effettuare l'operazione aritmetica dell'addizione tra 98


due numeri binari indipendentemente dal segno dei due numeri. È sufficiente sommare i due numeri in
complemento a 2 ignorando il riporto. Ad esempio, per sommare il numero negativo (-10)10 con il numero
positivo (+20)(10) tramite la rappresentazione in complemento a 2 si procede nel seguente modo:

Il numero positivo (+20)(10)resta invariato mentre il numero negativo (−10)(10)deve essere elaborato
mediante la regola della rappresentazione in complemento a due. In primo luogo, procediamo a calcolare il
valore assoluto (senza segno) del numero binario.

Utilizziamo il valore assoluto del numero binario per il calcolo del complemento invertendo tutte le cifre
(bit) del numero da zero a uno e viceversa.

Infine, per ottenere il complemento a due si addiziona il numero ottenuto con il numero uno
(00000001)2.

Una volta calcolata la rappresentazione in complemento a due del numero negativo si somma il numero
binario (11110110)2 con il numero positivo dell'operazione aritmetica (00010100)2senza tenere in conto
l'eventuale resto finale.

Decodifica veloce
- Se bit più a sinistra =0 è positivo, altrimenti negativo
- Se positivo, basta leggere gli altri bit
- Se negativo, scrivere gli stessi bit da destra a sinistra fino al primo 1, poi complementare, e poi
leggere
- Es.: 1010 è sicuramente negativo (bit più a sinistra vale −2(𝑛−1)), rappresenta 0110 (6), quindi −6

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Da 𝑘 a −𝑘, quindi: 99

Altra decodifica veloce


- Data la rappresentazione di 𝑘 (positivo), −𝑘 si può anche ottenere così:
o Complemento bit a bit della rappresentazione di 𝑘
o Somma di 1 al risultato
- Esempio:
o 2 = 0010
o Complemento: 1101
o 1101 + 1 = 1110
o −2 = 111

Benefici
- Una sola rappresentazione dello zero
- Le operazioni aritmetiche sono facili
- La negazione è facile
o 3 = 00000011
o Complemento Booleano 11111100
o Somma di 1 11111101

Esercizi
- Da complemento a 2 a base 10:
o 00011 → 3
o 01111 → 15
o 11100 → -4
o 11010 → 6
o 00000 → 0
o 10000 → -16
- Da base 10 a complemento a 2 su 8 bit:
o 6 → 00000110
o -6 → 11111010
o 13 → 00001101
o -1 → 11111111
o 0 → 00000000
- Numero più grande e più piccolo per la notazione in complemento a 2 su:
o 4 bit → 23 - 1
o 6 bit → 25 - 1
o 8 bit → 27 – 1

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Conversione tra diverse lunghezze 100


- Da una rappresentazione su n bit ad una rappresentazione dello stesso numero su 𝑚 𝑏𝑖𝑡 (𝑚 > 𝑛)
- Modulo e segno: facile
o Bit di segno nel bit più a sinistra
o 𝑚 − 𝑛 zeri aggiunti a sinistra
- Esempio (da 4 a 8 bit): 1001 è 10000001
- Complemento a 2: stessa cosa del modulo e segno per numeri positivi
- Per numeri negativi: replicare il bit più significativo dalla posizione attuale alla nuova
Esempi:
o +18 (8 𝑏𝑖𝑡) = 00010010
o +18 (16 𝑏𝑖𝑡) = 00000000 00010010
o −18 (8 𝑏𝑖𝑡) = 11101110
o −18 (16 𝑏𝑖𝑡) = 11111111 11101110

Opposto su numeri a complemento a 2


Strutturato in due passi: Complemento e Somma 1.
Rappresentiamo il caso speciale 1, come segue:

Così come il caso speciale 2, come nuovamente segue:

Per la somma, è una normale somma binaria (basta controllare il bit


più significativo per l’overflow). Per la sottrazione, invece, basta avere i
circuiti per somma e complemento.
- (4 𝑏𝑖𝑡): 7 − 5 = 7 + (−5) = 0111 + 1011 = 0010
- 5 = 0101 → − 5 = 1011

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Ecco l’hardware necessario per somma e sottrazione: 101


Nei circuiti digitali, un sommatore-
sottrattore binario è in grado di eseguire sia
l'addizione che la sottrazione di numeri
binari in un unico circuito. L'operazione
eseguita dipende dal valore binario del
segnale di controllo. È uno dei componenti
dell'ALU (Unità Logica Aritmetica).

Consideriamo due numeri binari a 4 bit A e B come ingressi al Circuito Digitale per l'operazione con le cifre
𝐴0 𝐴1 𝐴2 𝐴3 𝑝𝑒𝑟 𝐴
𝐵0 𝐵1 𝐵2 𝐵3 𝑝𝑒𝑟 𝐵
Il circuito è composto da 4 sommatori completi, poiché stiamo eseguendo operazioni su numeri a 4 bit. C'è
una linea di controllo K che contiene un valore binario di 0 o 1 che determina l'operazione di addizione o
sottrazione.

Come mostrato in figura, il primo


sommatore completo ha la linea di controllo direttamente come ingresso (input carry Cin), l'ingresso A0 (il
bit meno significativo di A) è direttamente inserito nel sommatore completo. Il terzo ingresso è XOR di B0 e
K. Le due uscite prodotte sono Somma/Differenza (S0) e Riporto/Carry (C0).

Se il valore di K (linea di controllo) è 1, l'uscita di B0(XOR)K=B0′(complemento B0). L'operazione sarebbe


quindi A+(B0′). Ora la sottrazione del complemento a 2 per due numeri A e B è data da A+B'. Questo
suggerisce che quando K=1, l'operazione eseguita sui numeri a quattro bit è la sottrazione.

Analogamente, se il valore di K=0, B0 (XOR) K=B0. L'operazione è A+B, ovvero una semplice addizione
binaria. Questo suggerisce che quando K=0, l'operazione eseguita sui numeri a quattro bit è l'addizione.

Quindi C0 viene passato in serie al secondo sommatore completo come una delle sue uscite. La
somma/differenza S0 viene registrata come il bit meno significativo della somma/differenza. A1, A2, A3
sono ingressi diretti al secondo, terzo e quarto sommatore completo. Il terzo ingresso è costituito da B1,

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

B2, B3, XORed (avendo eseguito lo XOR) con K, rispettivamente al secondo, terzo e quarto sommatore 102
completo. I riporti C1 e C2 vengono passati in serie al successivo sommatore completo come uno degli
ingressi. C3 diventa il riporto totale alla somma/differenza. S1, S2, S3 vengono registrati per formare il
risultato con S0.
Per un sommatore-sottrattore binario a n bit, si utilizza un numero n di sommatori completi.

Può succedere anche un overflow: quando si sommano due numeri positivi tali che il risultato è maggiore
del massimo numero positivo rappresentabile con i bit fissati (lo stesso per somma di due negativi). Se la
somma dà overflow, il risultato non è corretto. Come si riconosce? Basta guardare il bit più significativo
della risposta: se 0 (1) e i numeri sono entrambi negativi (positivi) è overflow. Su 4 bit, ad esempio:

Per la moltiplicazione, è più complessa; si calcola il prodotto parziale per ogni cifra e si sommano i prodotti
parziali. Esempio:

La moltiplicazione di due numeri binari senza segno, X e Y, può essere eseguita con l'algoritmo longhand/a
mano libera:
Si noti che i bit 0 in X contribuiscono con uno 0 al prodotto,
mentre i bit 1 in X contribuiscono con Y spostato a sinistra per
allinearsi con il bit corrispondente in X.

La base dell'algoritmo a mano lunga può essere compresa dalla


rappresentazione binaria dei numeri interi senza segno. Siano X
e Y numeri interi senza segno di n+1 bit:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il prodotto XY è dato da: 103

Ogni bit non nullo in X contribuisce con un termine costituito da Y moltiplicato per una potenza di 2.
Il prodotto di due numeri senza segno di n bit può richiedere fino a 2n bit poiché

L'overflow si verifica quando il prodotto è maggiore di n bit.

L'algoritmo di moltiplicazione a mano per i numeri interi senza segno a n bit può essere implementato
utilizzando l'addizione a n bit. Si noti che il bit meno significativo è determinato dal primo termine della
somma. Questo bit può essere memorizzato e il termine può essere spostato di 1 bit a destra in
preparazione dell'aggiunta del termine successivo. Questo processo viene ripetuto n volte per n bit.

In generale (spiegato nel dettaglio come qui, ma non chiesto) si ha da immagine l’hardware:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Moltiplicare numeri in complemento a 2 104


- Per la somma, i numeri in complemento a 2 possono essere considerati come numeri senza segno
Esempio:
- 1001 + 0011 = 1100
- Interi senza segno: 9 + 3 = 12
- Complemento a 2: − 7 + 3 = −4

Per la moltiplicazione questo non funziona! Non funziona se almeno uno dei due numeri è negativo.

Bisogna usare la rappresentazione in complemento a due per i prodotti parziali:

Problemi anche se moltiplicatore negativo.


Una possibile soluzione:
1. convertire I fattori negativi in numeri positivi
2. effettuare la moltiplicazione
3. se necessario (-+ o +-), cambiare di segno il risultato
Soluzione usata → Algoritmo di Booth (approfondimento messo solo per completezza).

L'algoritmo di Booth fornisce una procedura per moltiplicare i numeri interi binari nella rappresentazione a
complemento di 2 firmata in modo efficiente, cioè con un minor numero di addizioni/sottrazioni.
L'algoritmo si basa sul fatto che le stringhe di 0 nel moltiplicatore non richiedono alcuna addizione, ma solo
uno spostamento, mentre una stringa di 1 nel moltiplicatore dal peso del bit 2𝑘al peso 2𝑚 può essere
trattata come 2(𝑘+1) a 2𝑚. Come in tutti gli schemi di moltiplicazione, l'algoritmo di stand richiede l'esame
dei bit del moltiplicatore e lo spostamento del prodotto parziale. Prima dello spostamento, il moltiplicando
può essere aggiunto al prodotto parziale, sottratto al prodotto parziale o lasciato invariato secondo le
regole seguenti:
- Il moltiplicando viene sottratto dal prodotto parziale quando incontra il primo 1 meno significativo
in una stringa di 1 nel moltiplicatore.
- Il moltiplicando viene aggiunto al prodotto parziale quando si incontra il primo 0 (a condizione che
ci sia stato un precedente "1") in una stringa di 0 nel moltiplicatore.
- Il prodotto parziale non cambia quando il bit del moltiplicatore è identico al bit del moltiplicatore
precedente.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Per la divisione, invece, si basa sugli stessi principi della 105


moltiplicazione, ma usa traslazioni, somme e
sottrazioni ripetute (altro approfondimento messo solo
per completezza).

La divisione di ripristino viene solitamente eseguita sui


numeri frazionari in virgola fissa. Quando si
eseguono operazioni di divisione su due numeri,
l'algoritmo di divisione fornisce due dati, ossia il
quoziente e il resto. Questo algoritmo si basa sul
presupposto che 0 < D < N. Con l'aiuto dell'insieme di
cifre {0, 1}, nell'algoritmo di divisione ripristinante si forma
la cifra quoziente q.

In questo caso, il registro Q viene utilizzato per contenere il quoziente e il registro A per contenere il resto.
In questo caso, il divisore viene caricato nel registro M e il diviso a n bit viene caricato nel registro Q. 0 è il
valore iniziale di un registro. I valori di questi tipi di registri vengono ripristinati al momento dell'iterazione.
Per questo motivo si parla di ripristino.

Ora impareremo alcuni passaggi dell'algoritmo di divisione di ripristino, descritto come segue:

- Fase 1: in questa fase, i registri vengono inizializzati con il valore corrispondente, ossia il registro A conterrà
il valore 0, il registro M conterrà il divisore, il registro Q conterrà il dividendo, mentre N viene utilizzato per
specificare il numero di bit del dividendo.

- Fase 2: in questa fase, il registro A e il registro Q vengono trattati come una singola unità e il valore di
entrambi i registri viene spostato a sinistra.

- Fase 3: Successivamente, il valore del registro M verrà sottratto dal registro A. Il risultato della sottrazione
verrà memorizzato nel registro A.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Fase 4: ora si controlla il bit più significativo del registro A. Se questo bit del registro A è 0, allora il bit meno 106
significativo del registro Q sarà impostato con il valore 1. Se il bit più significativo di A è 0, allora il bit meno
significativo del registro Q sarà impostato con il valore 1. Se il bit più significativo di A è 1, allora il bit meno
significativo del registro Q verrà impostato con il valore 0 e ripristinerà il valore di A, ovvero ripristinerà il
valore del registro A prima della sottrazione con M.

- Fase 5: Successivamente, il valore di N viene decrementato. Qui n viene utilizzato come contatore.

- Fase 6: Se il valore di N è 0, il ciclo viene interrotto. In caso contrario, si deve tornare al passaggio 2.

- Passo 7: Questo è l'ultimo passo. In questo passaggio, il quoziente è contenuto nel registro Q e il resto è
contenuto nel registro A.

Ad esempio:
In questo esempio, verrà eseguito un algoritmo di ripristino della divisione.
1. Dividendo = 11
2. Divisore = 3

N M A Q Operation

4 00011 00000 1011 Initialize

00011 00001 011_ Shift left AQ

00011 11110 011_ A=A-M

00011 00001 0110 Q[0] = 0 And restore A

3 00011 00010 110_ Shift left AQ

00011 11111 110_ A=A-M

00011 00010 1100 Q[0] = 0

2 00011 00101 100_ Shift left AQ

00011 00010 100_ A=A-M

00011 00010 1001 Q[0] = 1

1 00011 00101 001_ Shift left AQ

00011 00010 001_ A=A-M

00011 00010 0011 Q[0] = 1


Non bisogna quindi dimenticare di ripristinare il valore del bit più significativo di A, che è 1. Quindi, il
registro A contiene il resto 2, mentre il registro Q contiene il quoziente 3.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

107
Rappresentazione e Aritmetica Numeri Reali
La rappresentazione dei numeri reali deve comprendere anche i numeri frazionari: essi possono anche
essere rappresentati in binario (comprendendo la virgola), ad es:

Se numero fisso (senza virgola), la rappresentazione è limitante; se invece esiste la virgola, dobbiamo saper
specificare dove si trova la virgola.

Conosciamo anche la notazione scientifica (decimale), per cui si eseguono arrotondamenti, rappresentando
numeri molto grandi o molto piccoli con poche cifre.

Lo stesso vale per i numeri binari, dove riconosciamo la struttura (poi descritta): +/− 𝑆𝑥𝐵(+/−𝐸).
- S: significando o mantissa (la parte prima della virgola, parte intera)
- Si assume la virgola dopo una cifra della mantissa
- B: base
La struttura in FP/Floating Point/virgola mobile è come segue:

I numeri in virgola mobile, di solito, vanno normalizzati; quindi, l’esponente è aggiustato in modo che il bit
più significativo della mantissa sia 1. Dato che è sempre 1 non c’è bisogno di specificarlo.

L’1 non viene rappresentato nei bit a disposizione → se 23 bit per la mantissa, posso rappresentare numeri
in [1,2). Se non normalizzato, aggiusto l’esponente: 0,1𝑥20 = 1,0𝑥2(−1)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I numeri rappresentabili a 32 bit sono come segue: 108

In merito invece alla densità ed alla precisione, si considera un esempio con 8 bit per l’esponente e 23 per la
mantissa (1 di segno ovviamente). Se più bit per l’esponente (e meno per la mantissa), espandiamo
l’intervallo rappresentabile, ma i numeri sono più distanti tra loro: si ha quindi minore precisione.
La precisione, infatti, aumenta solo aumentando il numero dei bit (a 32 bit si ha precisione singola, a 64 bit
precisione doppia).

Per la densità:

I numeri rappresentati con 2 bit di esponente


e 2 di mantissa:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Parliamo ora dello standard IEEE 754, che definisce un metodo per la rappresentazione dei numeri in 109
virgola mobile, o floating point. Il numero reale viene dapprima rappresentato in binario, convertendo
opportunamente la parte intera e la parte frazionaria.
Viene usato in formato singolo a 32 bit e a formato doppio a 64 bit, con un esponente con 8/11 bit, 1
implicito a sinistra della virgola e una serie di formati estesi (più bit per mantissa ed esponente) per risultati
intermedi (più precisi → minore possibilità di risultato finale con eccessivo arrotondamento).

Alcune combinazioni (es.: valori estremi dell’esponente) sono interpretate in modo speciale.
- Esponente polarizzato da 1 a 254 (cioè esponente da -126 a +127): numeri normalizzati non nulli in
virgola mobile → +/−2(𝑒−127)𝑥1. 𝑓.
- Esponente 0, mantissa (frazione) 0: rappresenta 0 positivo e negativo
- Esponente con tutti 1, mantissa 0: infinito positivo e negativo. L’overflow può essere errore o dare
il valore infinito come risultato
- Esponente 0, mantissa non nulla: numero denormalizzato
o Bit a sinistra della virgola: 0, vero esponente: -126
o Positivo o negativo
o Numero: 2^(−126) 𝑥 0. 𝑓
- Esponente tutti 1, mantissa non nulla: errore (Not A Number)

Per le singole operazioni:

1) Somma e sottrazione
Quattro fasi:
- Controllo dello zero
o Se uno dei due è 0, il risultato è l’altro numero
- Allineamento delle mantisse
o Rendere uguali gli esponenti
- Somma o sottrazione delle mantisse
- Normalizzazione del risultato
o Traslare a sinistra finché la cifra più significativa è diversa da 0

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

110

2) Moltiplicazione e divisione
Per la moltiplicazione, i significanti vengono moltiplicati, gli esponenti vengono sommati e il
risultato viene arrotondato e normalizzato.
Allo stesso modo, la divisione si ottiene sottraendo l'esponente del divisore dall'esponente del
dividendo e dividendo il significante del dividendo per il significante del divisore.
Non ci sono problemi di annullamento o di assorbimento con la moltiplicazione o la divisione,
anche se piccoli errori possono accumularsi quando le operazioni vengono eseguite in successione.
Può essere riassunto dei nei seguenti passi:
- Controllo dello zero
- Somma degli esponenti
- Sottrazione polarizzazione
- Moltiplicazione/divisione operandi
- Normalizzazione
- Arrotondamento

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Per ottenere maggiore precisione nel risultato raggiunto, si usano i bit di guardia. 111
Di solito operandi nei registri della ALU, che hanno più bit di quelli necessari per la mantissa +1 → i bit più a
destra sono messi a 0 e permettono di non perdere bit se i numeri vengono shiftati a destra.

Similmente, il risultato può essere arrotondato. Se il risultato è in un registro più lungo, quando lo si riporta
nel formato in virgola mobile, bisogna arrotondarlo.

Esercizi su virgola mobile

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

112

Linguaggio macchina
Il linguaggio macchina è un linguaggio di basso livello composto da numeri o bit binari che un computer può
comprendere. È noto anche come codice macchina o codice oggetto ed è estremamente difficile da
comprendere. L'unico linguaggio che il computer comprende è il linguaggio macchina. Tutti i programmi e i
linguaggi di programmazione, come Swift e C++, producono o eseguono programmi in linguaggio macchina
prima di essere eseguiti su un computer. Quando si esegue un compito specifico, anche il più piccolo
processo, il linguaggio macchina viene trasmesso al processore di sistema. I computer sono in grado di
comprendere solo i dati binari in quanto sono dispositivi digitali.

Gli elementi di un’istruzione macchina sono:


1) Codice operativo → Specifica l’operazione da eseguire
2) Riferimento all’operando sorgente → Specifica l’operando che rappresenta l’input dell’operazione
3) Riferimento all’operando risultato → Dove mettere il risultato
4) Riferimento all’istruzione successiva

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Gli operandi possono essere in vari punti: 113


- Memoria centrale ( o virtuale) → Si deve fornire l’indirizzo
- Registri della CPU → Ognuno ha un numero che lo identifica
- Dato immediato nella istruzione
- Dispositivi di I/O → Numero modulo o indirizzo di M

Le istruzioni vengono rappresentate come sequenze di bit (divise in campi), usando una rappresentazione
simbolica delle configurazioni di bit (es.: ADD, SUB, LOAD). Anche gli operandi hanno una rappresentazione
simbolica (es.: ADD A,B).
Ecco un esempio del formato di un’istruzione:

Similmente, ci sono vari tipi di istruzioni:


- Elaborazione dati → Istruzione aritmetiche e logiche, di solito sui registri della CPU
- Immagazzinamento dei dati in M o viceversa
- Trasferimento dei dati (I/O)
- Controllo del flusso del programma → Salto con o senza test

Per un’istruzione, sono necessari un certo numero di indirizzi:


- Un indirizzo per ogni operando (1 o 2)
- Uno per il risultato
- Indirizzo istruzione successiva
Quindi al massimo quattro indirizzi, tuttavia è molto raro, e sarebbe molto dispendioso. Di solito 1, 2 o 3
per gli operandi/risultati.

Per il numero di indirizzi, abbiamo varie situazioni:


- 1 indirizzo
o il secondo indirizzo è implicito
o di solito si tratta di un registro (accumulatore)
o situazione tipica nei primi calcolatori
- 0 indirizzi
o tutti gli indirizzi sono impliciti
o utilizza una pila (stack)
n Ad esempio, 𝑐 = 𝑎 + 𝑏 è realizzato come segue
𝑝𝑢𝑠ℎ 𝑎 𝑝𝑢𝑠ℎ 𝑏 𝑎𝑑𝑑 𝑝𝑜𝑝 𝑐

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Quindi: 114
- Meno indirizzi → istruzioni più elementari (e più corte), quindi CPU meno complessa. Però più
istruzioni per lo stesso programma → tempo di esecuzione più lungo.
- Più indirizzi → istruzioni più complesse
- Indirizzo di M o registro: meno bit per indicare un registro

Per progettare un set/insieme di istruzioni, si deve pensare ad un certo numero di cose:


- Repertorio → quante e quali operazioni
- Tipi di dato → su quali dati
- Formato → lunghezza, numero indirizzi, dimensione campi, ...
- Registri → numero dei registri della CPU indirizzabili dalle istruzioni
- Indirizzamento → modo di specificare gli indirizzi degli operandi
Gli operandi sono di vario tipo:
indirizzi (interi senza segno), numeri (limite al modulo o alla precisione), caratteri, dati logici.

I numeri, in particolare, sono interi a virgola fissa/virgola mobile e, nel caso di operazioni di I/O, si usano i
decimali impaccati (packed decimals), che specifica un metodo di codifica dei numeri decimali utilizzando
ogni byte per rappresentare due cifre decimali. La rappresentazione decimale a pacchetto memorizza i dati
decimali con precisione esatta. La parte frazionaria del numero è determinata dal formato perché non ci
sono mantissa ed esponente separati.

In merito ai caratteri, si usa il classico standard del codice ASCII (American Standard Code for Information
Exchange). Un carattere = 7 bit → 128 caratteri in totale.
Caratteri alfabetici + caratteri di controllo. Di solito 8 bit: un bit per controllo di errori di trasmissione
(controllo di parità).

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I dati logici sono formati da n bit, invece che un singolo dato, per manipolare i bit separatamente. 115
Per l’architettura x86 (Intel), si hanno come caratteristiche per tipi di dati trattati:

Più specificamente:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

116

Ulteriormente, descriviamo i vari tipi di operazioni:


- Trasferimento Dati, per cui si deve specificare
o Sorgente: dove è il dato da trasferire
o Destinazione: dove va messo
o Lunghezza del dato da trasferire.
Diverse scelte:
o Esempio: codici operativi diversi per trasferimenti diversi (L, LH, LR,LER, LE, LDR, LD in IBM
370) o stesso codice (MOV in VAX) ma specifica nell’operando
- Aritmetiche, per cui somma, sottrazione, moltiplicazione, divisione n Interi con segno sempre
(spesso anche per numeri in virgola mobile). Possono includere anche: incremento, decremento,
negazione, valore assoluto
- Logiche, quindi operazioni sui bit (AND, OR, NOT, XOR, EQUAL). Possono essere eseguite in
parallelo su tutti i bit di un registro (And come maschera)

Esempio di operazione:

Similmente, esistono operazioni di:


- Shift, quindi ci si sposta o verso destra o verso sinistra logicamente/aritmeticamente
- Rotazione, quindi una volta che si shifta, arrivando alla fine, si riparte dall’inizio o dalla fine

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Trasferimento del controllo: 117


1) Salto condizionato (branch)
o Es.: salta a x se il risultato è 0
o Registro condizione o più operandi
▪ Es.: BRE R1, R2, X
o Perché saltare?
▪ Istruzioni da eseguire varie
volte
▪ Decidere cosa fare sulla
base del verificarsi di certe
condizioni
▪ Programmazione modulare

2) Salto incondizionato (skip)


o Scavalca un’istruzione e passa alla successiva
o Non ha operandi
o Per usare lo spazio operandi
▪ es.: incrementa e salta se 0 (istruzione ISZ)

Introduciamo il concetto di procedura: pezzo di


programma a cui si dà un nome, in modo da
eseguirlo (chiamarlo) da qualunque punto di un
programma indicando il suo nome. Si usano per
due motivi:
- Risparmio codice: scrivo solo una volta
un pezzo di codice
- Modularità: posso affidare la scrittura
di una procedura ad un altro
programmatore
Due istruzioni principali:
- Chiamata e ritorno (entrambe di salto)
Similmente, possono essere annidate (caso di
esempio qui a fianco).

Luoghi per memorizzare l’indirizzo di ritorno


- Un registro
o CALL X provoca:
RN  PC + D (D=lunghezza istruzione)
PC  X
- Inizio della procedura chiamata
o CALL X provoca:
X  PC + D
PC  X+1
- Cima della pila: porzione di M dove le scritture/letture avvengono sempre in cima
o Gli indirizzi di ritorno vengono memorizzati in cima alla pila, uno dopo l’altro, e vengono
presi nell’ordine inverso alla chiusura delle procedure. Esempio di uso nell’immagine:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Parliamo di linguaggio assembly, un tipo di linguaggio di programmazione di basso livello destinato a 118
comunicare direttamente con l'hardware di un computer. A differenza del linguaggio macchina, che
consiste in caratteri binari ed esadecimali, i linguaggi assembly sono progettati per essere leggibili
dall'uomo. I codici operativi sono dati da simboli e indirizzi numerici sono indirizzi simbolici (per operandi
ed istruzioni). Per tradurre dall’linguaggio assembly a linguaggio macchina, vi è l’assembler/assemblatore.
I byte sono memorizzati in due modi (introducendo il concetto di endianness, un termine che descrive
l'ordine in cui una sequenza di byte viene memorizzata nella memoria del computer)
- Big endian, che significa che i dati vengono archiviati prima big end. In più byte, il primo byte è il più
grande o rappresenta il valore primario.
- Little endian, in cui i dati vengono memorizzati prima di tutto. In questo caso, con pezzi multibyte, è
l’ultimo pezzo più grande o che ha il valore primario a cui vengono aggiunti o concatenati i valori
successivi.

Modi di indirizzamernto
Vari modi di specificare l’indirizzo
degli operandi
- Immediato, per cui l’operando è parte dell’istruzione (campo indirizzo)
o Vantaggio: nessun accesso in M per prendere l’operando
o Svantaggio: valore limitato dalla dimensione del campo indirizzo

- Diretto, per cui il campo indirizzo = indirizzo dell’operando


o Esempio: ADD A
▪ Somma il contenuto della cella A all’accumulatore
▪ Bisogna andare in M all’indirizzo A per trovare l’operando
o Un singolo accesso in M per prendere l’operando
o Spazio di indirizzamento limitato

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Indiretto, per cio il campo indirizzo contiene l’indirizzo di una cella di M, che contiene l’indirizzo 119
dell’operando
o Vantaggio: parole di lunghezza N permettono di indirizzare 2N entità diverse
▪ In realtà 2K, dove K è la lunghezza del campo indirizzo
o Svantaggio: due accessi in M per ottenere l’operando.
o Esempio: ADD A
▪ Somma il contenuto della cella puntata dal contenuto di A all’accumulatore

- Registro, per cui l’operando è in un registro indicato nel campo indirizzo. Si ha un numero limitato
di registri e in generale pochi bit necessari per il campo indirizzo.
o Istruzioni più corte
o Fase di fetch più veloce (nessun accesso in M per prendere l’operando)

- Registro indiretto, con lo stesso principio dell’indirizzamento indiretto.


o L’operando è in una cella di M puntata dal contenuto del registro R
o Grande spazio di indirizzamento (2n)
o Un accesso in meno in M rispetto all’indirizzamento indiretto

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

- Spiazzamento, che è una combinazione di indirizzamento diretto e indirizzamento registro 120


indiretto.
o Il campo indirizzo ha due sottocampi
▪ A = valore di base (diretto)
▪ R = registro che contiene l’indirizzo di un valore da sommare ad A per ottenere
l’indirizzo
▪ o viceversa (R base e A spiazzamento)

- Relativo, una versione dell’indirizzamento con spiazzamento


o R = registro PC (program counter)
o Indirizzo dell’operando = A + (PC)
▪ A celle dalla cella di M puntata da PC
- Indirizzamento, registro base
o A contiene lo spiazzamento
o R contiene il puntatore all’indirizzo base
▪ R può essere esplicito o implicito

L’indicizzazione usa infatti funziona in questo modo:


- A = base
- R = spiazzamento
- Esempio: elenco di dati memorizzati in M a partire da un indirizzo A
o Per accedere a tutti, la sequenza di indirizzi è A, A+1, A+2, ...
o A viene messo nel campo indirizzo e il registro (indice) contiene 0 all’inizio e viene
incrementato di 1 dopo ogni accesso

- Indirizzamento a pila, come detto lo stack,


sequenza lineare di locazioni riservate di M.
o Puntatore (nel registro SP, stack
pointer) con l’indirizzo della cima
della pila
o L’operando è sulla cima della pila
o Quindi è un esempio di
indirizzamento a registro indiretto

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

121

Le istruzioni, appunto, hanno un loro formato, quindi la struttura dei campi dell’istruzione. Include il codice
operativo, in modo implicito o esplicito, uno o più operandi (avendo di solito più di un formato per un
linguaggio macchina). La lunghezza delle istruzioni condiziona ed è condizionata da:
- Dimensione della M
- Organizzazione della M
- Struttura del bus
- Complessità della CPU
- Velocità della CPU
Si cerca quindi un compromesso tra repertorio di istruzioni potente e necessità di risparmiare spazio

Per quanto riguarda l’allocazione dei bit:


- Vari modi di indirizzamento
- Vari numeri di operandi (di solito 1 o 2)
- Registri verso M (di solito almeno 32 registri)
- Banchi di registri (esempio: Pentium ha due banchi)
o Due banchi da 8 registri ciascuno è solo 3 bit per indicare un registro (il codice operativo
indica il banco)
- Intervallo di indirizzi
- Granularità degli indirizzi (es.: byte o parola)
o L’indirizzamento di byte richiede più bit ma è utile (es. per manipolare caratteri)

Esempio del PDP-8, primo minicomputer commerciale della storia che abbia avuto successo:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

E similmente del PDP-10, versione successiva, condividendo la stessa lunghezza di parole a 36 bit e 122
estendendo leggermente il set di istruzioni (ma con una migliore implementazione hardware). Alcuni
aspetti del set di istruzioni sono unici, in particolare le istruzioni “byte”, che hanno operato su campi di bit
di qualsiasi dimensione da 1 a 36 bit inclusi secondo la definizione più generale di un byte come una
sequenza contigua di un numero fisso di bit.

- Lunghezza variabile, che funziona con una serie di indirizzi per i singoli operandi. Questa è la base
anche per il successivo sviluppo del formato ibrido:

Similmente, ecco un formato che usa questa idea, quello del PDP-11

(Il PDP-11 includeva una serie di caratteristiche innovative nel suo set di istruzioni e registri generici
aggiuntivi che lo rendevano molto più facile da programmare rispetto ai modelli precedenti della
serie PDP. Inoltre, l'innovativo sistema Unibus consentiva di interfacciare facilmente dispositivi
esterni al sistema utilizzando l'accesso diretto alla memoria, aprendo il sistema a un'ampia gamma
di periferiche. Il PDP-11 sostituì il PDP-8 in molte applicazioni di calcolo in tempo reale, anche se le
due linee di prodotti vissero in parallelo per oltre 10 anni. La facilità di programmazione del PDP-11
lo rese molto popolare anche per usi informatici generici.
Il design del PDP-11 ha ispirato la progettazione di microprocessori della fine degli anni '70, tra cui
l'Intel x86[1] e il Motorola 68000)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

E del VAX 123


("VAX" era originariamente un acronimo per l'espressione in lingua inglese Virtual Address
eXtension, in quanto VAX era visto come un'estensione a 32 bit della precedente architettura a 16
bit del PDP-11; le prime versioni di VAX implementavano una modalità di funzionamento
"compatibile" che emulava molte delle istruzioni del PDP-11. Le versioni successive abbandonarono
questa modalità e anche alcune delle istruzioni CISC meno utilizzate, a favore di un maggiore uso
del microcodice o dell'emulazione da parte del software del sistema operativo.)

Similmente, il formato delle istruzioni x86:


(Un'istruzione x86-64 può essere lunga al massimo 15 byte. È costituita dai seguenti componenti nell'ordine
indicato, dove i prefissi sono all'indirizzo meno significativo (più basso) in memoria:
- Prefissi legacy (1-4 byte, facoltativi)
- Opcode con prefissi (1-4 byte, obbligatorio)
- ModR/M (1 byte, se richiesto)
- SIB (1 byte, se richiesto)
- Spostamento (1, 2, 4 o 8 byte, se richiesto)
- Immediato (1, 2, 4 o 8 byte, se richiesto)

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

124
Struttura e funzione del processore
Compiti CPU:
- Prelevare istruzioni
- Interpretare istruzioni
- Prelevare dati
- Elaborare dati
- Scrivere (memorizzare) dati
Come abbiamo già visto, collabora con i bus di sistema (sx) con relativa struttura interna (dx):

Il livello più alto della gerarchia di memoria sono i registri, spazio per la CPU di memorizzazione dati e con
un numero di funzioni svolte in base all’impianto progettuale della stessa CPU.
Sono di due tipi:
- Registri utente
o usati dal “programmatore” per memorizzare internamente alla CPU i dati da elaborare
o Usati per la memorizzazione di dati/indirizzi/codici di condizione
- Registri di controllo e di stato
o usati dall’unità di controllo per monitorare le operazioni della CPU
o usati dai programmi del Sistema Operativo (SO) per controllare l’esecuzione dei programmi

Normalmente, il “programmatore” è l’umano che programma codice che viene interpretato sotto forma di
assembler e linker per istruzioni mnemoniche per la macchina e scritte in un linguaggio ad alto livello (C,
C++, Java).

Parliamo anche dei registri ad uso generale, dedicati a varie funzioni ma anche per funzioni specifiche.
Similmente, possono essere usati per contenere dati (es. accumulatore) ed indirizzi (es. indirizzo base di un
segmento di memoria).
La memoria principale, infatti, può essere organizzata come insieme di segmenti o spazi di indirizzamento
multipli:
− “visibili” al “programmatore”, che riferisce logicamente una locazione di memoria riferendo il segmento e
la posizione della locazione all’interno del segmento:
es. segmento 4, locazione 1024
− come supporto a questa “visione” della memoria, occorre poter indicare dove, all’interno della memoria
fisica, inizia il segmento (base) e la sua lunghezza (limite) es. il segmento 4 ha base = 00EF9445hex e limite =
4MB
− quindi occorrono dei registri dove memorizzare tali informazioni
Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I registri, infatti, sono: 125


- Registri veramente ad uso generale
o Aumentano la flessibilità e le opzioni disponibili al programmatore “a basso livello”
o Aumentano la dimensione dell’istruzione e la sua complessità (perché ?)
- Registri specializzati
o Istruzioni più piccole e più veloci
o Meno flessibili
Perché aumenta dimensione e complessità?

Quanti registri generali?


− Tipicamente tra 8 e 32
− Meno di 8 = più riferimenti (accessi) alla memoria principale (perché ?)
− Più di 32 non riducono i riferimenti alla memoria ed occupano molto spazio nella CPU

Perché più accessi?

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Quanto lunghi (in bit)? 126


− Abbastanza grandi da contenere un indirizzo della memoria principale
− Abbastanza grandi da contenere una “full word”
− è spesso possibile combinare due registri dati in modo da ottenerne uno di dimensione doppia
− Es.: programmazione in C
o double int a;
o long int a;

Similmente, esistono registri per la memorizzazione di codici di condizione, avendo insiemi di bit individuali
( es. Il risultato dell’ultima operazione era zero). Possono essere letti (implicitamente) da programma
(es. “Jump if zero” (salta se zero)). Non possono (tipicamente) essere impostati da programma.

Questo insieme di codici di condizioni esiste nel Program Status Word, costituito da un insieme di bit per
codici di condizione (segno dell’ultimo risultato, zero, riporto/carry, uguale, overflow, gestione interrupt,
supervisore, ecc.)

Quindi, per eseguire istruzioni privilegiate e agendo direttamente sul Kernel, quindi attuando modifiche a
componenti critiche del sistema, si attiva la cosiddetta Superuser Mode/Supervisor Mode, come
superutente, non disponibile al normale utente.
Ci possono essere registri che puntano a tabella delle pagine della memoria virtuale, blocchi di controllo dei
processi, ecc.
Un esempio di organizzazione dei registri:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Recuperiamo il funzionamento del ciclo esecutivo (Fetch/Execute) delle istruzioni (già visto 127
precedentemente) in una versione revisionata.
Per recuperare gli operandi di una istruzione può essere necessario accedere alla memoria. La modalità di
indirizzamento indiretto per specificare la locazione in memoria degli operandi richiede più accessi in
memoria. L’indirettezza si può considerare come un sottociclo del ciclo fetch/execute.

Il flusso dei dati, in generale, dipende


dall’architettura della CPU e in generale:
- Fetch
o PC contiene l’indirizzo della
istruzione successiva
o Tale indirizzo viene spostato in
MAR
o L’indirizzo viene emesso sul bus
degli indirizzi
o La unità di controllo richiede
una lettura in memoria
principale
o Il risultato della lettura in
memoria principale viene
inviato nel bus dati, copiato in
MBR, ed infine in IR
o Contemporaneamente il PC
viene incrementato

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il flusso dei dati (Data Fetch) esegue come 128


operazioni questa serie:
- IR è esaminato
- Se il codice operativo della istruzione
richiede un indirizzamento indiretto, si
esegue il ciclo di indirettezza
o gli N bit più a destra di MBR
vengono trasferiti nel MAR
o L’unità di controllo richiede la
lettura dalla memoria principale
o Il risultato della lettura (indirizzo
dell’operando) viene trasferito
in MBR

L’esecuzione, invece, assume molte forme e


dipende dall’istruzione da eseguire.
Può includere:
- lettura/scrittura della memoria
- Input/Output
- Trasferimento di dati fra registri e/o in registri
- Operazioni della ALU

L’interruzione invece è semplice e prevedibile:


- Contenuto corrente del PC deve essere
salvato per permettere il ripristino della
esecuzione dopo la gestione dell’interruzione
o Contenuto PC copiato in MBR
o Indirizzo di locazione di memoria speciale
(es. stack pointer) caricato in MAR
o Contenuto di MBR scritto in memoria
- PC caricato con l’indirizzo della prima
istruzione della routine di gestione della
interruzione
- Fetch della istruzione puntata da PC

La fase di prelievo della istruzione accede alla memoria principale mentre la fase di esecuzione di solito non
lo fa. Si può prelevare l’istruzione successiva durante l’esecuzione della istruzione corrente. Questa
operazione si chiama “instruction prefetch”.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il prefetch non raddoppia le prestazioni: 129


- L’esecuzione di istruzioni jump o branch possono rendere vano il prefetch
- La fase di prelievo è tipicamente più breve della fase di esecuzione
- Occorre aggiungere più fasi per migliorare le prestazioni
- Può essere inutile perché:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

130
Pipeline
Il principio della pipeline permette di eseguire più attività contemporaneamente, completando il lavoro in
meno tempo.
in 3 unità di Tempo
• 1 esecutore termina 1
solo lavoro
• 3 esecutori terminano 3
lavori

In generale, quindi otteniamo un parallelismo totale, eseguendo tante attività allo stesso tempo.
Tuttavia, possono esistere dipendenze funzionali tra le singole attività.

Dipendenza funzionale tra lavori successivi


• ogni lavoro è diviso in 3 fasi successive
• la fase 1 di Lavoro i deve essere eseguita dopo la fase 1 del precedente Lavoro i-1
Esecutori generici
• ognuno esegue un lavoro completo
• a regime ha lo stesso throughput del
parallelismo totale
• ognuno ha le risorse necessarie per ogni
fase: sistema totalmente replicato

Esecutori specializzati
• ogni esecutore svolge sempre la stessa fase di ognuno dei lavori
• ogni esecutore ha solo le risorse per eseguire quella fase
• ogni lavoro passa da un esecutore all’altro
• a regime ha lo stesso throughput del parallelismo totale, ma usando meno risorse

Quindi:
• si decompone un lavoro in fasi successive
- un prodotto deve passare una fase dopo l’altra
- ogni fase è realizzata da un diverso operatore
- nello stesso istante
• prodotti diversi sono in fasi diverse (parallelismo)
- l’istante successivo
• ogni fase ripete lo stesso lavoro sul prodotto successivo,
• ogni lavoro avanza alla fase successiva
– operatori/fasi diverse usano risorse diverse evitando conflitti (se possibile)
Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Nello stesso istante, istruzioni diverse sono in fasi diverse e, nell’istante successivo, ogni fase ripete lo 131
stesso lavoro sull’istruzione avanza alla fase successiva.
Ogni fase è realizzata da una diversa unità funzionale della CPU ed operatori/fasi diverse usano risorse
diverse evitando conflitti (se possibile). Tra due fasi successive si inseriscono dei buffer (registri) su cui si
scrivono/leggono dati temporanei utili alla fase successiva.

Come detto, il prefetch non raddoppia le prestazioni:


• la fase di fetch è più breve, ma prima di poter iniziare il fetch successivo deve attendere che termini
anche la fase di esecuzione
• se viene eseguito un jump o branch, la prossima istruzione da eseguire non è quella che è appena stata
prelevata:
- la fase di fetch deve attendere che la fase execute le fornisca l’indirizzo a cui prelevare l’istruzione
- la successiva fase di execute deve attendere che sia prelevata l’istruzione, perche’ quella pre-
fetched non era valida

La suddivisione in fasi aggiunge overhead per spostare i dati nei buffer tra una fase e l’altra e per gestire il
cambiamento di fase. Questo overhead potrebbe essere significativo quando:
– istruzioni successive dipendono logicamente da quelle precedenti,
– quando ci sono salti,
– quando ci sono conflitti negli accessi alla memoria/registri
La gestione logica e l’overhead aumentano con l’aumentare del numero di fasi della pipeline; occorre una
progettazione accurata per ottenere risultati ottimali con una complessità ragionevole.
Per aumentare le prestazioni bisogna
• decomporre il lavoro in un maggior numero di fasi
• cercare di rendere le fasi più indipendenti e con una durata simile

L’evoluzione ideale della pipeline segue: in questo caso, esegue 9 istruzioni in 14 unità di tempo invece di
9x6=54.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Si può vedere la temporizzazione a lato 132

La performance della pipeline, quindi, viene così descritta:

Idealmente, le performance della pipeline:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

133

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Ci sono varie situazioni in cui l’istruzione successiva non può essere eseguita nel ciclo di clock 134
immediatamente successivo (stallo – pipeline bubble) non si raggiunge il parallelismo massimo, cosiddette
pipeline hazards.
1. Sbilanciamento delle fasi
- Durate diverse per fase e per istruzione, e non tutte le fasi richiedono lo stesso tempo di esecuzione
(es.: lettura di un operando tramite registro rispetto ad una mediante indirizzamento indiretto).
La suddivisione in fasi va fatta in base all’istruzione più onerosa e non tutte le istruzioni richiedono le stesse
fasi e le stesse risorse.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

135

Possibili soluzioni:
• Decomporre fasi onerose in più sottofasi → Costo elevato e bassa utilizzazione
• Duplicare gli esecutori delle fasi più onerose e farli operare in parallelo → CPU moderne hanno una ALU
in aritmetica intera ed una in aritmetica a virgola mobile

2. Problemi strutturali (structural hazards)


– Due fasi competono per usare la stessa risorsa, es. memoria in FI, FO, WO, dato che richiedono di
accedere ad una stessa risorsa nello stesso ciclo di clock e quindi gli accessi devono avvenire in sequenza e
non in parallelo.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

136

Possibili soluzioni:
• introdurre fasi non operative (nop)
• suddividere le memorie permettendo accessi paralleli: una memoria cache per le istruzioni e una per i
dati

3. Dipendenza dai dati (data hazards)


– Un’istruzione dipende dal risultato di un’istruzione precedente ancora in pipeline. Una fase non può
essere eseguita in un certo ciclo di clock perché i dati di cui ha bisogno non sono ancora disponibili e deve
attendere che termini l’elaborazione di un’altra fase. Un dato modificato nell’esecuzione dell’istruzione
corrente può dover essere utilizzato dalla fase FO dell’istruzione successiva.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

137

𝑖𝑠𝑡𝑟𝑢𝑧𝑖𝑜𝑛𝑒 𝑖
𝑖𝑠𝑡𝑟𝑢𝑧𝑖𝑜𝑛𝑒 𝑖 + 1
• Read after Write : “lettura dopo scrittura” (esempio di prima)
- i+1 legge prima che i abbia scritto
• Write after Write : “scrittura dopo scrittura”
- i+1 scrive prima che i abbia scritto
• Write after Read: “scrittura dopo lettura”
- i+1 scrive prima che i abbia letto (caso raro in pipeline)

4. Dipendenza dal controllo (control hazards)


– Istruzioni che alterano la sequenzialità, es. salti (condizionati o no), chiamate e ritorni da procedure,
interruzioni. L’istruzione successiva ha bisogno dei dati prima che la precedente li abbia prodotti. Dipende
dall’architettura della pipeline: da come sono definiti i suoi stadi e come sono implementate le istruzioni

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Possibili soluzioni: 138


1. Introduzione di fasi non operative (nop-stallo)

2. Propagazione in avanti del dato richiesto (data forwarding – bypassing)

3. Riordino delle istruzioni

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

139

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

140

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

141

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

142

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Uno dei maggiori problemi della progettazione della pipeline è assicurare un flusso regolare di istruzioni 143
– violato da salti condizionati, salti non condizionati, chiamate e ritorni da procedure
– se la fase fetch ha caricato un’istruzione errata, va scartata
– queste istruzioni sono circa il 30% del totale medio di un programma
Possibili soluzioni:
• mettere in stallo la pipeline finché non si è calcolato l’indirizzo della prossima → istruzione semplice ma
inefficiente
• individuare le istruzioni critiche e aggiungere un’apposita logica di controllo → si complica il compilatore
e hardware specifico

Soluzioni per salti condizionati


1. flussi multipli (multiple streams)
– replica la prima parte della pipeline, EI esclusa, per entrambi i rami possibili

2. prefetch anche dell’istruzione target


– anticipa il fetch dell’istruzione target oltre a quella successiva al salto
– se il salto è preso, trova l’istruzione già caricata
– in ogni caso una parte della pipeline deve essere scartata

3. buffer circolare (loop buffer) → buffer senza prefetch, capienza 256 bytes, indirizzato a byte
– è una memoria piccola e molto veloce che mantiene le ultime n istruzioni prelevate
– in caso di salto l’hardware controlla se l’istruzione target è tra quelle già dentro il buffer, così da evitare il
fetch
– utile in caso di loop, specie se il buffer contiene tutte le istruzioni nel loop, così vengono prelevate dalla
memoria una sola volta
– può essere accoppiato al pre-fetch: riempio il buffer con un po’ di istruzioni sequenzialmente successive
alla corrente. Per molti if-then-else i due rami sono istruzioni vicine, quindi probabilmente entrambe già
nel buffer

Dato l’indirizzo target di salto/branch, controllo se c’è


nel buffer:
– gli 8 bit meno significativi sono usati come indice nel
buffer
– gli altri bit più significativi si usano per controllare se
la destinazione del salto sta già nel buffer

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

144

4. predizione dei salti – cerco di predire se il salto sarà intrapreso o no

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Gli approcci dinamici di predizione cercano di migliorare la qualità della predizione sul salto memorizzando 145
la storia delle istruzioni di salto condizionato di uno specifico programma. Ad ogni istruzione di salto
condizionato associo 1 (o 2) bit per ricordare la storia recente dell’istruzione, i.e. se l’ultima (e la penultima)
volta il salto è stato preso . I bit sono memorizzati in una locazione temporanea ad accesso molto veloce.

Si ha una predizione dinamica:


1) con 2 bit, appunto usando un paio di bit per ricordare come è andata la predizione degli ultimi due
salti. Per invertire la predizione ci vogliono 2 errori consecutivi e in questo modo a regime fa un
solo errore per ciclo
Per ogni istruzione di salto condizionato uso
1/2 bit
• per ricordare se l’ultima volta che ho
eseguito quella stessa istruzione il salto è
stato fatto o no
• se incontro di nuovo quell’istruzione e
l’ultima volta aveva provocato il salto
• allora predico che salterà, quindi carico la
pipeline con le istruzioni a partire dalla
destinazione del salto
• se ho fatto la scelta sbagliata, le istruzioni
caricate vengono eliminate

2) con 1 bit, due cicli innestati, supponiamo che per entrambi si iteri una sola volta

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

146

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

147

Tornando alla predizione dinamica 2 bit:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

148

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

149

La predizione dei dinamica usa il buffer di predizione dei salti/branch prediction buffer/branch history
table) è una piccola memoria associata allo stadio fetch della pipeline
Ogni riga della tabella è costituita da 3 elementi:
1. indirizzo istruzione salto,
2. i bit di predizione
3. l’indirizzo destinazione del salto (o l’istruzione destinazione stessa), così quando la predizione è di saltare
non devo attendere che si ri-decodifichi il target del salto (se la previsione è errata dovrò eliminare le
istruzioni errate e caricare quelle corrette

Da questa predizione dei salti, dipendono due note vulnerabilità dei processori:
Spectre e Meltdown sono vulnerabilità di sicurezza estremamente pericolose che consentono a soggetti
malintenzionati di aggirare le protezioni di sicurezza del sistema presenti in quasi tutti i dispositivi recenti
dotati di CPU, non solo PC, server e smartphone, ma anche dispositivi Internet of Things (IoT) come router e
smart TV. Sfruttando il duo, è possibile leggere la memoria di sistema protetta, ottenendo l'accesso a
password, chiavi di crittografia e altre informazioni sensibili.

Spectre e Meltdown sono esempi rappresentativi di attacchi di "esecuzione transitoria", che si basano su
difetti di progettazione hardware nell'implementazione dell'esecuzione speculativa, del pipelining delle
istruzioni e dell'esecuzione fuori ordine nelle CPU moderne. Sebbene questi tre elementi siano essenziali
per le ottimizzazioni delle prestazioni insite nei processori moderni, le loro implementazioni variano tra i
produttori di CPU e le microarchitetture; di conseguenza, non tutte le varianti di Spectre e Meltdown sono
sfruttabili su tutte le microarchitetture.

Come funziona Spectre

Secondo gli autori originali del documento Spectre, "[induce] una vittima a eseguire speculativamente
operazioni che non si verificherebbero durante l'elaborazione in ordine strettamente seriale delle istruzioni
del programma e che fanno trapelare informazioni riservate della vittima attraverso un canale nascosto
all'avversario".

Gli attacchi Spectre si svolgono in tre fasi:


1) La fase di setup, in cui il processore viene distratto per fare "una previsione speculativa errata".
2) Il processore esegue speculativamente le istruzioni dal contesto di destinazione in un canale
nascosto della microarchitettura.
3) I dati sensibili vengono recuperati. Questo può essere fatto temporizzando l'accesso agli indirizzi di
memoria nella cache della CPU.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Come funziona Meltdown 150


Meltdown sfrutta una race condition tra l'accesso alla memoria e il controllo del livello di privilegio durante
l'elaborazione di un'istruzione. In combinazione con un attacco parallelo alla cache della CPU, i controlli dei
livelli di privilegio possono essere aggirati, consentendo l'accesso alla memoria utilizzata dal sistema
operativo o da altri processi in esecuzione. In determinate circostanze, questo può essere utilizzato per
leggere la memoria nei container software.

Gli attacchi Meltdown, secondo gli autori del documento originale, si svolgono in tre fasi:
1) Il contenuto di una posizione di memoria scelta dall'attaccante, inaccessibile a quest'ultimo, viene
caricato in un registro.
2) Un'istruzione transitoria accede a una linea della cache in base al contenuto segreto del registro.
3) L'aggressore utilizza Flush+Reload per determinare la linea di cache a cui si accede e quindi il
segreto memorizzato nella posizione di memoria scelta.

Nonostante la pubblicazione simultanea di Spectre e Meltdown, i due sfruttano proprietà diverse delle
CPU; l'unico punto in comune tra Spectre e Meltdown è l'utilizzo dell'esecuzione transitoria.
Spectre si basa su eventi di errori sulla predizione dei branch per sollecitare istruzioni transitorie. Spectre
funziona solo con i dati accessibili architettonicamente a un'applicazione. Meltdown, invece, si basa su
istruzioni transitorie non ordinate in seguito a un'eccezione. Meltdown si basa su istruzioni transitorie
inaccessibili architettonicamente a un'applicazione.

In ultimo, si ha il salto ritardato (delayed branch). Finché non si sa se ci sarà o no il salto (l’istruzione è in
pipeline), invece di restare in stallo si può eseguire un’istruzione che non dipende dal salto.
L’istruzione successiva al salto è definita come branch delay slot. Il compilatore cerca di allocare nel branch
delay slot una istruzione “opportuna” (magari inutile ma non dannosa) e la CPU esegue sempre l’istruzione
del branch delay slot e, solo dopo, altera, se necessario, la sequenza di esecuzione delle istruzioni.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

151

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

152

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

153

Un esempio vero di pipelining: Intel 80846 Pipelining

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

154

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

155
Esercizi pipeline

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

156

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

157

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

158
Filosofia RISC
Tra le principali innovazioni dei computer, esiste proprio l’architettura per processori RISC (Reduced
Instruction Set Computer), che è un tipo di architettura di microprocessore che utilizza un piccolo insieme
di istruzioni altamente ottimizzate, anziché un insieme di istruzioni altamente specializzate come quelle
tipiche di altre architetture. Il RISC è un'alternativa all'architettura CISC (Complex Instruction Set
Computing) ed è spesso considerato la tecnologia di architettura CPU più efficiente oggi disponibile.

Con il RISC, un'unità di elaborazione centrale (CPU) implementa il principio di progettazione del processore
che prevede istruzioni semplificate che possono fare meno cose ma possono essere eseguite più
rapidamente. Il risultato è un miglioramento delle prestazioni. Una caratteristica fondamentale del RISC è
che consente agli sviluppatori di aumentare il set di registri e di incrementare il parallelismo interno,
aumentando il numero di thread paralleli eseguiti dalla CPU e aumentando la velocità di esecuzione delle
istruzioni della CPU. ARM, o "Advanced RISC Machine", è una famiglia specifica di architetture a set di
istruzioni basate su un'architettura a set di istruzioni ridotto sviluppata da Arm Ltd.

Essa è frutto della co-evoluzione tra hardware e linguaggi di programmazione, arrivando a linguaggi ad alto
livello, che permettono di esprimere l’algoritmo risolutivo in modo più conciso, lasciano al compilatore il
compito di gestire i dettagli e supportano costrutti di programmazione strutturata. Sussiste un gap
semantico tra i linguaggi HLL/High Level Languages descritti e il linguaggio macchina, infatti si hanno:
- esecuzione inefficiente
- taglia eccessiva del programma in linguaggio macchina
- complessità del compilatore
In tutta risposta, i progettisti hardware hanno ampliato il set di istruzioni, hanno creato svariati modi di
indirizzamento e si cerca un’implementazione hardware di costrutti di linguaggi ad alto livello (es. CASE
(switch) su architettura VAX).
In questo modo:
- si semplifica il lavoro del compilatore
- migliora l’efficienza dell’esecuzione (sequenze di operazioni complesse implementate tramite
microcodice)
- si supportano linguaggi HL più complessi

Alternativamente, si cerca di individuare le caratteristiche e i pattern di esecuzione delle istruzioni


macchina generate dai programmi dei linguaggi ad alto livello e per semplificare l’architettura.
Con questo si intende che si vuole:
- semplificare le funzionalità del processore e la sua interazione con la memoria
- tipo e frequenza d’uso degli operandi determinano l’organizzazione della memoria e i modi di
indirizzamento
- organizzazione del flusso dell’esecuzione (pipeline) e suo controllo.
Occorre in generale:
- fare un’ analisi delle istruzioni macchina generate dai programmi scritti in HLL
- misure dinamiche: raccolte eseguendo il programma e contando il numero di occorrenze di una
certa proprietà o di una certa caratteristica. (le misure statiche si basano solo sul programma
sorgente, che non dice quante volte è eseguita un’istruzione)
Nei vari linguaggi sussiste una predominanza di istruzioni di assegnamento (quindi si deve rendere
efficiente il trasferimento dei dati) e molte istruzioni condizionali (controllando le dipendenze dai salti).
Si deve anche capire quali sono le istruzioni macchina che rubano più tempo: normalmente sono i cicli, le
chiamate e le condizioni.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

159

In generale, dipende da:


• quale linguaggio HL
• quale tipo di applicazione
• quale architettura sottostante
• resta rappresentativa delle contemporanee architetture CISC (Il termine CISC sta per ''Complex
Instruction Set Computer''. Si tratta di un progetto di CPU basato su singoli comandi, che sono in grado di
eseguire operazioni in più fasi).

Per gli operandi, costituiti principalmente variabili scalari locali- L’ottimizzazione si deve concentrare
sull’accesso alle variabili locali scalari.
In generale, le chiamate di procedura sono le istruzioni che consumano più tempo, va quindi trovata
un’implementazione efficiente. Due aspetti significativi:
– il numero di parametri e variabili gestite
– il livello di annidamento (nesting)
Misurazioni:
– meno di 6 parametri, meno di 6 variabili locali
– la maggior parte degli operandi sono variabili locali
– poco annidamento di chiamate di procedure

Strategia migliore per supportare i linguaggi di alto livello:


• non rendere le istruzioni macchina più simili alle istruzioni di HLL
• ottimizzare le performance dei pattern più usati e più time-consuming
1. ampio numero di registri o loro uso ottimizzato dal compilatore
– per ottimizzare gli accessi agli operandi (abbiamo visto che sono istruzioni molto frequenti, con operandi
perlopiù scalari e locali, quindi è utile ridurre gli accessi alla memoria aumentando gli accessi ai registri)
2. progettazione accurata della pipeline
– gestione delle dipendenze dal controllo dovute a (frequenti) salti e chiamate di procedure evitando i
prefetch errati
3. set di istruzioni semplificato (ridotto) e implementato in maniera efficiente.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Per quanto riguarda i registri, hanno indirizzi più brevi di quelli per l’uso di cache e memoria principale e 160
bisogna assicurare che gli operandi usati siano il più possibile mantenuti nei registri, minimizzando i
trasferimenti memoria-registro.
• Soluzione hardware:
– aumentare il numero di registri,
– così si mantengono più variabili per più tempo
• Soluzione software:
– il compilatore massimizza l’uso dei registri
– le variabili più usate per ogni intervallo di tempo sono allocate nei registri
– richiede sofisticate tecniche di analisi dei programmi
In generale, si cerca di memorizzare nei registri le variabili scalari locali (le più frequenti) e si hanno pochi
registri per le variabili locali (quindi, i valori utili per ogni procedura attualmente in uso, con lo scope).

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Idea per usare al meglio i (tanti) registri general-purpose: 161


• suddividere i registri in molti piccoli gruppi (di taglia fissa)
• ogni procedura ha il proprio gruppo/finestra di registri
• è sempre visibile (indirizzabile) un solo gruppo/finestra: quello corrispondente alla procedura
attiva in quel momento.
Una chiamata di procedura:
– cambia automaticamente il gruppo di registri da usare
– invece di provocare il salvataggio dei dati in memoria
– al ritorno viene riselezionato il gruppo di registri assegnato in precedenza alla procedura chiamante
– le finestre relative a procedure adiacenti sono parzialmente sovrapposte, in modo da facilitare il
passaggio dei parametri.

Usiamo quindi le cosiddette finestre di registri, in cui ogni gruppo/finestra è diviso in tre sottogruppi.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Quante finestre di registri? 162


– una per chiamata di procedura attivata (nesting)
– c’è spazio per un numero limitato: solo le più recenti
– le attivazioni precedenti vanno salvate in memoria e poi recuperate quando diminuisce il nesting

I registri sono organizzati a buffer circolare, come segue:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

163

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Parliamo anche delle variabili globali, cioè variabili accessibili da qualunque procedura, e più di una. 164
Dove memorizzarle?
- il compilatore le alloca in memoria, ma è poco efficiente se sono usate spesso
- Soluzione: usare un gruppo di registri ad hoc, disponibili a tutte le procedure
o Scopo: trovare gli operandi il più possibile nei registri e minimizzare le operazioni di
load/store
o Soluzione software: l’architettura RISC può avere pochi registri (16-32) il cui uso viene
ottimizzato dal compilatore
▪ Linguaggi ad alto livello non fanno riferimento esplicito ai registri, eccezione in C:
register int

Continuando con l’ottimizzazione dei registri, occorre decidere quale registro simbolico (quale variabile)
assegnare a quale registro reale in ogni momento.
Si hanno 𝑚 compiti da eseguire, n risorse, con 𝑚 >> 𝑛. Decidere quale compito assegnare a quale risorsa
in ogni momento (es. m voli da effettuare, n aerei).
Equivale a risolvere un problema di colorazione di un grafo:
– assegnare un colore ad ogni nodo in modo che nodi adiacenti abbiano colori diversi usando il minimo
numero di colori

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Qui i nodi (tanti) corrispondono ai registri simbolici e due nodi sono collegati da un arco se i due registri 165
simbolici (variabili) sono “in vita” nello stesso intervallo di tempo/porzione di codice. I colori (pochi)
corrispondono ai registri reali ed i nodi dello stesso colore possono essere assegnati allo stesso registro
reale. Se servono più colori di quanti sono i registri reali, allora i nodi che non riescono ad essere colorati
vanno memorizzati in memoria principale.

Decidere se un grafo è colorabile con k colori è un problema non risolvibile polinomialmente → NP-
Completo e si usano algoritmi efficienti per casi specifici, usando 32/64 registri fisici che spesso si
dimostrano sufficienti.

CISC
Ora parliamo di CISC, appunto, quindi un ampio insieme di istruzioni, istruzioni più complesse per
semplificare compilatore e migliorare performance. Il compilatore deve generare “buone” sequenze di
istruzioni macchina, cioè brevi e veloci da eseguire. Un’ istruzione complessa può essere eseguita più
velocemente di una serie di istruzioni più semplici, ma:
- l’unità di controllo diventa più complessa
- il controllo microprogrammato necessita di più spazio
- quindi si rallenta l’esecuzione delle istruzioni più semplici, che restano le più frequenti

Queste le principali caratteristiche:


• un’ istruzione per ciclo di clock
– (instruction cycle): tempo impiegato per fare fetch-decode-execute-write di un’istruzione elementare.
– RISC: hanno un ciclo esecutivo che dura un solo machine cycle, quindi se la pipeline è piena, ad ogni ciclo
di clock termina un’istruzione
– istruzioni CISC richiedono più di un ciclo;
• operazioni da registro a registro, tranne LOAD e STORE
– CISC attuali hanno anche operazioni memory-to-memory e register/memory
– poichè si usano di frequente scalari locali, aumentando o ottimizzando i
registri la maggior parte degli operandi stanno a lungo nei registri.
• pochi e semplici modi di indirizzamento
– indirizzo di registro, spiazzamento (relativo a PC)
– si semplifica l’istruzione e l’unità di controllo
• pochi e semplici formati fissi per le istruzioni
– campi e opcode a dimensione fissa, così la decodifica dell’opcode e l’accesso ai registri per gli operandi
possono essere simultanei

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

– istruzioni a lunghezza fissa sono allineate con la lunghezza delle parole, quindi il fetch è ottimizzato per
prelevare (multipli di) una parola 166
– la regolarità facilita le ottimizzazioni del compilatore
– più responsivo agli interrupt, controllati tra due istruzioni più semplici
• unità di controllo cablata:
– se cablata (cioè hardware) è meno flessibile ma più veloce
– se microprogrammata più flessibile ma meno veloce

Non è evidente quale sia l’architettura nettamente migliore. Problemi per fare un confronto:
– Non esistono architetture RISC e CISC che siano direttamente confrontabili
– Non esiste un set completo di programmi di test
– Difficoltà nel separare gli effetti dovuti all’hardware rispetto a quelli dovuti al compilatore
– Molti confronti sono stati svolti su macchine prototipali e semplificate e non su macchine commerciali
– Molte CPU commerciali utilizzano idee provenienti da entrambe le filosofie:
• PowerPC architettura RISC con elementi CISC
• Pentium II architettura CISC con elementi RISC

Le architetture specifiche per il dominio (domain-specific architectures) sono l'unica opzione per migliorare
le prestazioni, dato che i benefici della legge di Moore iniziano a svanire:
Un'architettura software specifica per il dominio (DSSA) è un insieme di componenti software:
- specializzati per un particolare dominio
- generalizzati per un uso efficace in tutto il dominio e composti in una struttura standardizzata
(topologia) efficace per costruire applicazioni di successo.

Similmente, confrontiamo i registri con la cache:

Il riferimento ad uno scalare cambia a seconda che si usi un banco a registri oppure una cache:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

167
Architettura MIPS-32
Studiamo i processori MIPS (Microprocessor without Interlocked Pipeline Stages) come esempio di
architettura RISC, un’architettura sperimentale sviluppata a Stanford negli anni ‘80 e poi sviluppata
commercialmente.
Istruzioni:
• Tutte le istruzioni di dimensione 32 bit
• Tutte le operazioni sui dati sono da registro a registro
– le istruzioni che manipolano i dati usano i valori dei registri
• le operazioni sulla memoria:
– solo load e store, per trasferire dati tra memoria e registri
– nessuna operazione memoria-memoria
• quindi tutte le istruzioni operano su registri, es add $1, $2, $3

Registri:
– 32 registri di 32 bit
– si indicano con $1, $2, $3…. $0 contiene sempre 0

Dati:
• Registri possono essere caricati con byte, mezze parole, e parole
• i registri sono a 32 bit, quindi un dato “più corto” può essere “allungato” riempiendo i bit rimanenti con 0
o estendendo il segno (cioè replicandolo)

I modi di indirizzamento sono diversi: immediato, displacement/spiazzamento ma anche indiretta registro


(displacement a 0) e assoluta (registro 0 come registro base).
Fornisce 32 bit per tutte le istruzioni con 3 formati diversi:

La dimensione fissa di opcode e di riferimenti a registri semplifica Instruction Decode e Fetch di Operandi.
Esaminiamo i formati singolarmente.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Per il formato R, usato per istruzioni aritmetiche e logiche. 6 campi a dimensione fissa: 168

Per il formato I, istruzioni load/store, immediate e salto condizionato:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

169

Poi il formato J, per il salto incondizionato:

Le istruzioni MIPS hanno un ciclo esecutivo preciso:


1. IF Instruction Fetch

2. ID Instruction Decode / register fetch

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

3. EX Execution / address calculation 170


– tutte le istruzioni usano la ALU (tranne salto incondizionato):
– operazioni logico-aritmetiche
– load/store e jump per calcolare l’indirizzo
– salti condizionati per calcolare la condizione

4. MEM Memory access / branch completion

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

5. WB Write Back: scrittura del risultato nei registri 171

Nel dettaglio, sulle singole istruzioni MIPS:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

172

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Schema di implementazione di MIPS: 173


• diverse unità funzionali (es. banco di registri, ALU, memoria…)
• loro connessioni
• manca unità di contro llo e linee di controllo

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

174

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

175

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

176

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

177

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Per la pipeline si ha: 178


- 1 ciclo di clock per fase/stadio
- 1 ciclo di clock per IF, ID, EX, MEM, WB
- 1 istruzione in 5 cicli di clock
- 1 ciclo di clock completa 5 fasi di 5 istruzioni diverse (a regime)
- ogni ciclo di clock termina un’istruzione (a regime)
Similmente, il gruppo di registri delle pipeline, quindi i pipeline registers (pipeline latches). I dati utili a fasi
(anche non immediatamente) successive sono memorizzati nel registro successivo e i registri memorizzano
sia dati che segnali di controllo (utili in seguito). In ogni istante registri diversi contengono dati relativi ad
istruzioni diverse.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

179

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

180

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

181

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

182

Analizziamo nel dettaglio i segnali di controllo:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

183

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

184

Per l’unità di controllo, le fasi IF e ID non dipendono dai valori dei segnali di controllo; in fase ID si possono
calcolare i segnali corretti per le fasi successive e i segnali sono calcolati in ID per poi essere propagati
attraverso i registri di pipeline.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Nella Pipeline MIPS è possibile individuare tutte le dipendenze dai dati nella fase ID. Se si rileva una 185
dipendenza dai dati per una istruzione, questa va in stallo prima di essere rilasciata (issued, cioè quando
una passa dalla fase ID a quella EX). Inoltre, sempre nella fase ID, è possibile determinare che tipo di data
forwarding adottare per evitare lo stallo ed anche predisporre gli opportuni segnali di controllo.
Esempio: realizziamo un forwarding nella fase EX per una dipendenza di tipo RAW (Read After Write) con
sorgente che proviene da una istruzione load (load interlock).
Vediamo l’esempio di una dipendenza RAW per le istruzioni Load:

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

186

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

187

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

188

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

189

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

190

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

191

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

192

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

193

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

‘ 194

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

195

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

196

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

197

Processori multicore
I microprocessori hanno visto una crescita esponenziale delle prestazioni, con grossi miglioramento della
organizzazione e grande incremento della frequenza di clock
Similmente, una grande crescita del parallelismo, attraverso le pipeline o le pipeline parallele (superscalari)
Un approccio più aggressivo consiste nel dotare il processore di più unità di elaborazione per gestire diverse
istruzioni in parallelo in ogni fase di elaborazione. In questo modo, diverse istruzioni iniziano l'esecuzione
nello stesso ciclo di clock e si dice che il processo utilizza un'emissione multipla. Tali processori sono in
grado di raggiungere un throughput di esecuzione delle istruzioni superiore a un'istruzione per ciclo.
Questo conduce ad usare le superscalari anche per il multithreading.
Problemi
- Maggiore complessità richiede logica più complessa
- Aumento dell’area del chip per supportare il parallelismo
- Più difficile da progettare, realizzare e verificare (debug)

La potenza cresce esponenzialmente con la densità del chip e la frequenza del clock
Rimedio: usare più spazio per la cache, meno densa e richiede molta meno potenza (ordini di magnitudine)
Nel 2015, si usano 100 miliardi di transistor in 300mm2 sul “die” (chip) e anche in cache di 100MB
possiedono 1 miliardo di transistor per la logica.
Regola di Pollack: Le prestazioni sono all’incirca proporzionali alla radice quadrata dell’incremento in
complessità
Il raddoppio in complessità restituisce il 40% in più di prestazione. Architetture multicore hanno il
potenziale per ottenere un miglioramento quasi lineare- Improbabile che un core possa utilizzare
efficacemente tutta la memoria cache.

I vantaggi prestazionali dipendono dallo sfruttamento efficace delle risorse parallele. Anche una piccola
quantità di codice seriale ha un impatto significativo sulle prestazioni. Il 10% di codice intrinsecamente
seriale eseguito su un sistema a 8 processori dà un incremento di prestazioni di solo 4,7 volte.
Overhead dovuto alla comunicazione, distribuzione del lavoro e mantenimento della coerenza della cache
Alcune applicazioni effettivamente sfruttano i processori multicore, soprattutto con un codice molto
sequenziale, seguendo direttamente la crescita del numero dei processori.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Il processore multicore dipende anche dalla struttura di lavoro utilizzata. Alcuni sistemi di lavoro non sono 198
in grado di gestire processori multicore che richiedono una maggiore potenza. Supponiamo di avere un
processore rapido, allora utilizzerà una maggiore quantità di energia, causando un elevato utilizzo della
batteria del PC. Nel caso in cui si stia giocando ad un gioco ad alto contenuto di design, è necessaria
un'ulteriore forza di gestione e una maggiore potenza di preparazione implica un maggiore utilizzo di
energia, per cui la batteria del PC evapora rapidamente.

I processori multicore sono utilizzati nei campi seguenti:


- Disposizione di incredibili illustrazioni
- Progettazione supportata da PC (CAD)
- Applicazioni visive e sonore
- Giochi 3D
- Modifiche video
- Lavoratori basati sull'informazione
- Codifica

Nell’organizzazione multicore, si ha un certo numero di core per chip, diversi livelli di cache per chip e una
certa quantità di cache condivisa.
Una tra le varie alternative, tra i vari tipi di cache multilivello (che utilizzano più di un livello di
implementazione della cache per rendere la velocità di accesso alla cache quasi uguale alla velocità della
CPU e per contenere un gran numero di oggetti della cache), vediamo che ce ne sono diverse, distinte tra:
- Cache L1 dedicata, con una serie di core e la main memory con una cache di livello 2
- Cache L2 dedicata, cioè una cache L2 per ogni core
- Cache L2 condivisa, quindi una cache L2 condivisa tra tutti i core
- Cache L3 condivisa. quindi una cache L3 condivisa tra tutti i core

Vantaggi di una cache L2 condivisa:


- Riduzione (accidentale) del numero di miss totali
- Dati condivisi da più core non sono replicati a livello di cache (a livello 2, ma possibile replicazione a
livello 1)
- Con appropriati algoritmi di sostituzione dei blocchi, la quantità di cache dedicata ad ogni core è
dinamica
- Thread con minore località possono utilizzare più spazio di cache
- Comunicazione fra processi (anche in esecuzione su core diversi) facilitata dall’utilizzo della
memoria condivisa
- Problema della coerenza della cache confinata al L1
- Cache L2 dedicate danno però un accesso alla memoria più rapido
- Migliori prestazioni per thread con forte località
- Anche una cache L3 condivisa può migliorare le prestazioni

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Alcuni esempi: 199

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Vantaggi dei processori multicore: 200


- I processori multicore possono portare a termine più lavoro rispetto ai processori a singolo centro.
- Risultano incredibili per le applicazioni multi-stringa.
- Possono portare a termine un lavoro sincrono a bassa ricorrenza.
- Possono gestire più informazioni rispetto ai processori a centro singolo.
- Possono portare a termine più lavoro consumando poca energia rispetto ai processori a centro
singolo.
- È possibile eseguire lavori complessi come il filtraggio dell'infezione contro l'infezione e la visione di
un film contemporaneamente.
- Poiché i due centri dei processori sono su un singolo chip, le riserve del PC sono sfruttate e le
informazioni non devono viaggiare più a lungo.
- Il PCB (circuito stampato) richiede meno spazio nel caso di utilizzo di processori multicore.
- I processori multicore sono ampiamente tolleranti ai guasti e sono molto affidabili.

Svantaggi dei processori multicore:


- Sono difficili da controllare rispetto ai processori a singolo centro.
- Sono più costosi di un processore a centro singolo.
- La loro velocità non è doppia rispetto a quella di un processore tipico.
- La presentazione del processore multicore dipende da come il cliente utilizza il PC.
- Consumano più energia.
- Questi processori si surriscaldano mentre svolgono più lavoro.
- Se un ciclo richiede una gestione diretta o consecutiva, il processore multicore deve rimanere in
funzione più a lungo.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

201
Esercizi pipeline parte 2

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

202

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

203

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

204

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

205

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

206

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

207

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

208

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

209

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

210

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

211

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

212

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

213

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

214

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

215

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

216

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

217

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

218

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

219
Contenuti integrativi: Circuiti e Microprogrammazione
Dato l’insieme di porte logiche di base:

NAND o NOR sono complete → circuiti con solo porte NAND o solo porte NOR.
Rete combinatoria: insieme di porte logiche connesse il cui output in un certo istante è funzione solo
dell’input in quell’istante. N input binari e m output binari e ad ogni combinazione di valori di ingresso
corrisponde una ed una sola combinazione di valori di uscita.
Utili per implementare la ALU e la connessione tra parti della CPU, ma non sono in grado di memorizzare
uno stato; quindi, non possono essere usate per implementare la memoria. Per questo servono le reti
sequenziali dall’output dipende non solo dall’input corrente, ma anche dalla storia passata degli input

Vediamo alcuni esempi di circuiti:


- I segnali sono discretizzati e di solito assumono solo due stati:

- I circuiti più complessi sono realizzati attraverso la combinazione di circuiti semplici (porte logiche)
- Le porte logiche sono realizzate tramite transistor (sono in pratica interruttori automatici)

Il multiplexer è un circuito capace di selezionare


uno tra i vari ingressi possibili e di trasferire il
dato in esso presente in uscita. È sempre dotato
di uno o più ingressi di selezione: m ingressi di
selezione servono per pilotare n=2m ingressi dati.
Solo uno degli ingressi viene trasferito all’output.
Ci sono “n” ingressi di controllo, che indicano
l’ingresso da trasferire:
- 2n linee di input ( D0 - D7)
- n linee di controllo (A,B,C)
- 1 linea di output (F)
- Per ogni combinazione degli ingressi di
controllo, 2n -1 delle porte AND hanno uscita 0,
l’altra fa uscire l’ingresso.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Un comparatore digitale o comparatore di 220


magnitudine è un dispositivo elettronico
hardware che riceve in input due segnali e in
output determina se sono uguali, o quale dei
due è il maggiore.

Per realizzare un comparatore per parole a più


bit occorre confrontare i bit di uguale peso delle
due parole, l'uscita segnalerà l'uguaglianza solo
nel caso in cui tutti i bit corrispondenti risultano
uguali.
- Comparatori ad 1 bit vengono collegati
tramite una porta NOR
- L’output vale 1 solo se tutti gli output
dei singoli comparatori ad 1 bit valgono
0 (Ai=Bi) per ogni i, cioè A=B

Traslatore (shifter: Trasla i bit in ingresso (D) di


una posizione, a sinistra o a destra a seconda
del valore del bit di controllo (C) (C=1 shift a
destra)

Esiste una variante della ALU ad 1 bit, che è una


semplice estensione a 32 bit di semplice
realizzazione. Essa realizza 4 operazioni
(selezionate da F0 e F1 ). AB, A or B, not(B), A+B.
ENA, ENB: per forzare a 0 gli input A ed INVA,
INVB: per invertire gli input.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

Concatenando n ALU ad 1 bit, si ottiene una ALU a n bit. F0 e F1 collegati a tutte le ALU, con riporto 221
intermedio propagato da una ALU alla successiva ed INC (corrispondente al carry in della ALU “0”) che
permette di sommare 1 al risultato in caso di addizione.

Flip flop: Forma più semplice di una rete sequenziale. Tanti tipi, ma due proprietà per tutti:
Essi sono bistabili:
- possono trovarsi in uno di due stati diversi
- in assenza di input, rimangono nello stato in cui sono
- memoria per un bit e due output, in cui uno è sempre il complemento dell’altro
Esiste il flip-flop D, con solo input (D). Usa segnale di clock per stabilizzare l’output (sincronizzazione) e
quando clock =0, gli output dei due AND sono 0 (stato stabile) e quando clock=1, gli input sono uno
l’opposto dell’altro → Q=D

L'elemento fondamentale dei registri può essere considerato il flip-flop di tipo D che costituisce, a tutti gli
effetti, una cella elementare di memoria. Esso è il circuito sincrono più semplice che realizza un registro.
- Memorizzazione (store): dati presentati in ingresso e clock da 0 a 1 (uscita riproduce ingresso)
- Mantenimento (hold): clock da 1 a 0 (poi costante); l’uscita rimane invariata indipendentemente
dal valore degli ingressi

La CPU si fa carico di realizzare il flusso di controllo appropriato per ogni istruzione tramite l’invio di
appositi segnali di controllo alla Parte Operativa attraverso l’unità di controllo (PC)
Vanno dunque:
- Definiti gli elementi di base del processore
- Definite le micro-operazioni eseguibili dal processore (trasferimento di dati tra i registri, oppure tra
i registri e le interfacce e viceversa o esecuzioni di operazioni aritmetico-logiche)
- Determinare le funzioni che la PC deve effettuare per l’esecuzione delle micro-operazioni
Gli elementi base sono:
- La ALU
- I registri
- Bus dati interno/esterno
- Unità di controllo

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

I compiti base della PC sono la serializzazione, che permette di determinare la giusta sequenza di micro- 222
operazioni da eseguire in funzione del codice operativo dell’istruzione e per l’esecuzione delle micro-
operazioni. Questo si realizza con appositi segnali di controllo.

La PC può essere:
- Cablata, realizzata
direttamente con circuiti digitali
(architetture RISC)
- Microprogrammata, con
maggiore flessibilità in fase di
progettazione che rende facile
modificare le sequenze di micro-
operazioni (tramite
microprogrammazione)

A livello firmware, il microprogramma riunisce i


frammenti di programma delle diverse operazioni.
Esso ha una struttura ciclica in cui si alterna
l’esecuzione della operazione speciale con
l’esecuzione della operazione esterna il cui codice e
dati da elaborare sono stati acquisiti dalla
operazione speciale.
Quindi, le variabili vengono controllate a cicli di
clock, rendendo utile lo scambio tramite apposite
variabili di condizionamento.

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

223
Altri esercizi pipeline

Scritto da Gabriel
Architettura degli elaboratori semplice (per davvero)

224

Scritto da Gabriel

Potrebbero piacerti anche