foglietto calc elettron4

annuncio pubblicitario
POSSIBILI PROVE:
1.
La memoria virtuale.
2.
Classificazione di Flynn per le architetture parallele
3.
Critiche al parallelismo: La legge di Amdhal
4.
Unità di controllo micro programmate
5.
Architetture RISC. Ragioni per la loro introduzione ed esempi.
6.
Architetture superscalari.
7.
Descrivere l’architettura di una CPU con organizzazione a pipeline. Illustrare con
un esempio le funzioni svolte dai singoli stadi
8.
Tecniche di accesso ai dati in una memoria cache. Illustrare le ragioni per le quali
questo tipo di accesso è critico e come la tecnica set-associative per l’accesso ai
dati di una cache risolva i problemi.
Spiegare la necessità di utilizzare arbitri per la gestione di interruzioni multiple.
Illustrare un esempio di soluzione.
a.
Descrivere i meccanismi di gestione delle interruzioni. Come
vengono gestite le interruzioni che si presentano
“contemporaneamente” alla CPU ? Come viene gestito
l’annidamento delle interruzioni ?
b.
Tecniche per la gestione di interruzioni multiple.
Accesso diretto alla memoria. Illustrare l’architettura del modulo e i vantaggi di
questa soluzione
Sistemi a bus. Protocolli per il trasferimento dei dati e le operazioni di lettura e
scrittura.
Gestione di I/O a controllo di programma
cluster
i sistemi di memoria
Arbitri: spiegare le funzioni svolte e i possibili modi di implementazione
(concentrato-distribuito).
9.
10.
11.
12.
13.
14.
15.
16.
Le politiche di sostituzione in una struttura di memoria gerarchica. (Fifo lru)
1
1 Memoria virtuale
2 Tassonomia di Flynn
In informatica, la memoria virtuale è una architettura di sistema capace di simulare uno spazio
di memoria centrale maggiore di quello fisicamente presente; questo risultato si raggiunge
utilizzando spazio di memoria secondaria su altri dispositivi, di solito le unità a disco. La
memoria centrale fisicamente presente diventa quindi la parte effettivamente utilizzata di quella
virtuale, più grande: questo stratagemma è utile in virtù del principio di località
Memoria paginata
Con questo schema la memoria viene divisa in pagine tutte della stessa grandezza (4 o 8
kilobyte): i programmi non hanno bisogno di sapere nulla su come è organizzata la memoria e
non devono avere nessuna struttura interna particolare; la esatta ubicazione e disposizione
fisica della memoria che occupano non li riguarda e tutto il sistema di memoria virtuale è
completamente gestito dalla MMU attraverso un complesso sistema di registri associativi.
Proprio questo sistema di registri è il punto debole di questo tipo di meccanismo: se il numero
delle pagine è molto grande (pagine di piccole dimensioni, oppure grandi quantità di memoria
virtuale da emulare) il meccanismo associativo può diventare troppo complesso, rallentando
sensibilmente l'accesso alla memoria (e quindi tutto il sistema).
Più dettagliatamente il meccanismo di gestione della memoria virtuale con paginazione è il
seguente. L'immagine di un processo è suddivisa in pagine di dimensione fissa. La memoria
principale (RAM) è suddivisa anch'essa in "pezzi", della stessa dimensione delle pagine, detti
page frame. Ad ogni processo è associata una tabella, mantenuta in memoria principale o
secondaria a seconda delle dimensioni, detta tabella delle pagine. Ogni entrata (riga) della
tabella delle pagine contiene:
Il numero di pagina per quella riga, Il bit present , Il bit modified, Il numero di frame
corrispondente.
Gli indirizzi logici sono rappresentati dalla coppia (nr. di pagina, offset). La traduzione avviene
in questo modo: si trova la riga corrispondente al numero di pagina dell'indirizzo logico, se il bit
Present è 0, la pagina non è presente in memoria principale, si genera quindi un Page Fault e
si attende che la pagina sia caricata in memoria, infine si genera l'indirizzo fisico (nr. frame,
offset).
Il bit Modified indica invece se la pagina è stata modificata o meno. Infatti se una pagina non è
stata modificata, al momento di effettuare lo swap nella memoria secondaria, non ha senso
riscrivere la pagine su disco. Risparmiando così tempo, e migliorando in parte le prestazioni.
Memoria segmentata
In questo caso il meccanismo di memoria virtuale è in parte software: i programmi che girano
su sistemi con memoria segmentata sono strutturati in segmenti funzionalmente omogenei: la
MMU tiene traccia di quali e quanti segmenti sono presenti in memoria e dove. Il vantaggio
principale di questo sistema è che sfrutta al massimo il già citato principio di località, riducendo
al minimo il ricorso allo spazio di swap: una volta che un programma ha in memoria centrale i
segmenti di cui necessita.
principio di località.
(Il principio di località enuncia che, se la CPU sta eseguendo una data istruzione, vuol dire che
con molta probabilità le prossime istruzioni da eseguire saranno ubicate nelle vicinanze di
quella in corso; vale a dire che, durante la normale esecuzione dei programmi, la CPU passa
molto tempo accedendo a zone di memoria ristrette e solo occasionalmente accede a locazioni
molto lontane. Inoltre, in genere gran parte del codice di cui sono costituiti i programmi viene
eseguito solo raramente, al verificarsi di errori o condizioni anomale: quindi succede spesso
che di tutto il codice che un programma carica in memoria ne venga realmente eseguita solo
una piccola parte.
classifica le architetture dei calcolatori 4 termini principali si ottiene la suddivisione principale:
single, multiple, instruction, data
SISD: unico calcolatore con un unico processoreArchitettura tradizionale con singola CPU che
elabora unaistruzione alla volta operando su un dato alla volta.
SIMD: stessa istruzione su più dati in parallelo. Gli array processor hanno un ALU comandate da
un’unica unità di controllo. Tutte le unità eseguono la stesse istruzione ma su dati differenti. E’
necessaria un’unica copia del programma da eseguire. I vector processor hanno unità funzionali
con pipeline che operano su pochi elementi per ogni colpo di clock. Più CPU operano in modo
sincrono eseguendo la stessa istruzione su dati diversi.
MIMD: più istruzioni su più dati. Si suddividono in due categorie: Il medesimo flusso di dati viene
elaborato da un insiemedi processori che eseguono istruzioni diverse.
classificazione di enslow�
Questa classificazione vuole individuare lecaratteristiche che deve avere una architettura per dirsi
distribuita� La classificazione di Enslow colloca learchitetture in uno spazio tridimensionaleUn
sistema è completamente distribuito selo è nelle tre dimensioni
Classificazione di Enslow
Enslow nel 1980 ha proposto di collocare le architetture dei sistemi di
elaborazione in uno spazio tridimensionale le cui dimensioni sono:
Elaborazione – Dati – Controllo
Unità di elaborazione singola.
Unità di elaborazione singola ma con più unità funzionali.
Unità di elaborazione multiple omogenee o eterogenee.
Base di dati centralizzata.
Base di dati distribuita fisicamente con direttorio centralizzato.
Base di dati distribuita fisicamente senza direttorio centralizzato.
Punto di controllo unico.
Relazioni di tipo master-slave statiche o dinamiche.
Punti di controllo autonomi e/o cooperanti.
Tra i due casi estremi (PC e Internet) si possono collocare tutte le
architetture di elaborazione esistenti.
SISD Singolo flusso di Istruzioni/Singolo flusso di Dati: convenzionalmente sono macchine con una
singola CPU capace solamente di effettuare operazioni aritmetiche fra scalari. Si tratta dunque di
un’architettura tradizionale con singola CPU che elabora un’istruzione alla volta operando su un
dato alla volta. SISD è anche sinonimo di computer sequenziale.
SIMD Singolo flusso di Istruzioni/Flusso di Dati multiplo: questo tipo di architettura include tutti i
computer paralleli recenti come ILLIAC IV che hanno una singola unità di controllo del programma
e molte unità indipendenti per l’esecuzione. In tale architettura più CPU operano in modo sincrono
eseguendo la stessa istruzione su dati diversi.
MISD Flusso di Istruzioni multiplo/Singolo flusso di Dati: pochi computer paralleli rientrano in
questa classe. Computer con capacità di fault-tolerance hanno diverse CPU che processano gli
stessi dati usando programmi differenti. Dunque il medesimo flusso di dati viene elaborato da un
insieme di processori che eseguono istruzioni diverse.
Secondo la classificazione di Enslow all’interno di un sistema ciò che è distribuito si identificacon:
Elaborazione, Dati, Controllo. Questa classificazione vuole individuare le caratteristiche che deve
avere un architettura per dirsi distribuita. Le architetture vengono collocate in uno spazio
tridimensionale (ogni asse corrisponde ai tre elementi per identificare un sistema distribuito) in cui
un sistema è completamente distribuito se lo è nelle tre dimensioni. Vediamo ora i singoli elementi
evidenziando per ognuno in senso crescente la distribuzione: • Distribuzione dell’elaborazione:
elaborazioni multiple omogenee o eterogenee.
ibuita fisicamente con direttorio
-slave statiche o
mi e/o cooperanti.
Gli estremi di un sistema classificato secondo Enslow sono il Personal Computer (con assenza di
distribuzione) e INTERNET che rappresenta la struttura distribuita più completa. All’interno di questi
due casi estremi si possono collocare tutte le architetture di elaborazione esistenti.
2
3 Legge di Amdahl
La legge di Amdahl, che ha preso il nome del progettista di computer Gene Amdahl, viene
usata per trovare il miglioramento atteso massimo in una architettura di calcolatori o in un
sistema informatico quando vengono migliorate solo alcune parti del sistema. Nella sua forma
più generale può essere espressa come:
"Il miglioramento che si può ottenere su una certa parte del sistema è limitato dalla frazione di
tempo in cui tale attività ha luogo"
che può essere ulteriormente semplificata nella pratica regoletta:
rendi veloce il caso piu frequente
La legge di Amdahl viene usata spesso nell'informatica parallela per predire l'aumento massimo
teorico di velocità che si ottiene usando più processori.
Nell'ambito dei sistemi software la legge di Amdahl può essere interpretata in modo più tecnico,
ma in parole povere significa che è l'algoritmo a decidere l'aumento di velocità, non il numero di
processori. Prima o poi si raggiunge un punto in cui non si può parallelizzare ulteriormente
l'algoritmo.
Più tecnicamente, la legge riguarda l'aumento di velocità ottenibile da un miglioramento a un
calcolo che influisce per una proporzione P di quel calcolo, dove il miglioramento riduce il
tempo di calcolo di un fattore S. (Per esempio, se un miglioramento può velocizzare il 30% del
calcolo, P sarà 0.3; se il miglioramento raddoppia la velocità della porzione modificata, S sarà
2.) La legge di Amdahl afferma che l'aumento di velocità complessivo prodotto dal
miglioramento sarà
1/((1-P)+P/s)
Parallelismo
Nel caso speciale del parallelismo, la legge di Amdahl afferma che se F è la frazione di un
calcolo che è sequenziale (cioè che non può beneficiare dal parallelismo), e (1 − F) è la
frazione che può essere parallelizzata, allora l'aumento massimo di velocità che si può ottenere
usando N processori è:
1/((F+(1-F))/N
4 Unità di controllo microprogrammate
L'architettura dei calcolatori: microprogrammazione.
I processori a logica programmata differiscono da quelli a logica dedicata soprattutto nell'unità di
governo, in quanto ora essa stessa è il risultato di esecuzione di un microprogramma: al suo
interno ci sono delle microunità che eseguono le operazioni elementari dei microprogrammi
associati alle istruzioni macchina riconosciute dalla CPU .
Realizzare un processore con questa tecnologia è più facile, soprattuto nel caso si desideri
espandere il suo set di istruzioni.
Nel precedente approccio a logica dedicata, era necessario realizzare una nuova rete logica per
ciascuna nuova istruzione, poi si procedeva alla sua integrazione con il circuito preesistente.
I microprogrammi sono memorizzati in un'area di memoria non cancellabile, ovvero di tipo ROM ,
che viene detta Memoria di Controllo. Ad ogni nuova revisione della CPU è sufficiente estendere
questa memoria per ospitare i nuovi microprogrammi i quali sono scritti in un particolare linguaggio
detto RTL .
Possiamo riassumere il discorso dicendo che la CPU a logica microprogrammata possiede un
proprio linguaggio a bassissimo livello attraverso il quale viene emulato il linguaggio macchina. Può
sembrare una cosa strana, ma torna utile in più di un'occasione. Per esempio una macchina C1
con un linguaggio L1, può eseguire i programmi scritti nel linguaggio L2 per la macchina C2,
semplicemente aggiungendo nella memoria di controllo della C1 i microprogrammi necessari per
interpretare il linguaggio L2. In questi casi si dice che C1 può emulare C2.
In teoria sarebbe possibile realizzare una CPU virtualmente compatibile con tutte le altre passate,
presenti e future. La sua memoria di controllo non dovrebbe essere del tipo ROM, ma del tipo non
volatile, ovvero una memoria che può essere alterata come la comunissima RAM , ma che non
perda il suo contenuto quando l'alimentazione è interrotta. In questo modo, anche dopo la sua
vendita sarà possibile estenderne le funzionalità, un po' come già accade oggi con gli
aggiornamenti del BIOS delle piastre madri delle architetture WINTEL .
.
CRITICHE AL PARALLELISMO
I supercomputer odierni sono una generazione indietro rispetto alle esigenze e una avanti
rispetto all'abilità dei programmatori.
• I problemi sono espressi in termini sequenziali.
• Esiste una quantità "enorme" di programmi già
sviluppati, sarebbe conveniente eseguirli più
velocemente.
• Legge di AMDAHL.
RAGIONI NON TECNICHE
L'introduzione e l’utilizzo efficace di sistemi di calcolo
paralleli per ottenere prestazioni superiori a quelle
delle architetture sequenziali presenta difficoltà che
non sono solamente di carattere tecnico.
La presenza di molti programmi già sviluppati per
architetture sequenziali, le conoscenze dei
programmatori e la loro abitudine a sviluppare
programmi su architetture sequenziali rappresentano
un investimento che non può essere trascurato.
Inoltre lo sfruttamento efficace di tutte le caratteristiche
delle architetture parallele richiede conoscenze che chi
sviluppa le applicazioni spesso non ha.
Effetti di operazioni sequenziali su di un sistema di
elaborazione parallelo.
• P: Numero di processori
• T(P): tempo di esecuzione di un programma a
parallelismo P.
• f: frazione di programma che deve essere eseguita
sequenzialmente.
Tempo di esecuzione del programma su di una
architettura a parallelismo P:
LEGGE DI AMDAHL
T(P) = f T(1) + (1-f) [T(1)/P]
Speed Up:
S(P) =T(1)/T(P) = 1/ [f + (1-f)/P] =P/[1 + f(P- 1)].
Efficienza:
E(P) = S(P)/P = 1/[1 + f(P- 1)].
CONSEGUENZE
• Una piccola porzione di codice non parallelizzabile può
avere un grande effetto globale.
• Riuscire a parallelizzare una porzione di codice
sequenziale consente di migliorare significativamente
le prestazioni.
3
5 Architetture CISC e architetture RISC
Quando i transistor disponibili su un solo chip erano pochi e i calcolatori venivano spesso
programmati in assembly, era naturale sfruttarli in modo tale da avere CPU con istruzioni
potenti, evolute e complesse: più queste erano vicine alle istruzioni dei linguaggi di
programmazione ad alto livello più il computer sarebbe stato facile da programmare, e i
programmi avrebbero occupato poco spazio in memoria (anch'essa poca e preziosa). Le CPU
progettate secondo questo approccio sono dette CISC ed avevano unità di controllo complesse
capaci di sfruttare al meglio pochi registri e i cui programmi erano di dimensioni relativamente
piccole.
CISC è l'acronimo di Complex Instruction Set Computer: tipicamente un processore di questo
tipo implementa un numero relativamente scarso (una decina) di registri di uso generale, ed ha
una unità di controllo microprogrammata: la logica del programma è memorizzata in una
memoria veloce situata nella parte di controllo, invece di essere espressa tramite una rete
combinatoria.
RISC (Reduced Instruction Set Computer)
RISC è l'acronimo di Reduced Instruction Set Computer. Il tipico set di istruzioni RISC è molto
piccolo, circa sessanta o settanta istruzioni molto elementari (logiche, aritmetiche e istruzioni di
trasferimento memoria-registro e registro-registro): hanno tutte lo stesso formato e la stessa
lunghezza, e molte vengono eseguite in un solo ciclo di clock. La diretta conseguenza di tale
scelta progettuale è che i processori RISC posseggono una unità di controllo semplice e a
bassa latenza, riservando invece molto spazio per i registri interni: una CPU RISC ha di solito
da un minimo di un centinaio ad alcune migliaia di registri interni generici, organizzati in un file
di registri. Il fatto di avere un formato unico di istruzione permette di strutturare l'unità di
controllo come una pipeline, cioè una catena di montaggio a più stadi: questa innovazione ha il
grosso vantaggio di ridurre il critical path interno alla CPU e consente ai RISC di raggiungere
frequenze di clock più alte rispetto agli analoghi CISC.
Nel caso di context-switch o di chiamata a subroutine o comunque di uso dello stack i RISC
spesso invece di accedere alla memoria di sistema usano un meccanismo chiamato register
renaming, che consiste nel rinominare i registri in modo da usare per la nuova esecuzione una
diversa zona del file di registri, senza dover accedere alla memoria ogni volta.
RISC vs CISC
La semplicità dei RISC si traduce in una minore espressività del linguaggio assembler: il
numero di word necessarie per esprimere una computazione in una macchina RISC è
maggiore/uguale alla controparte CISC: questo si traduce in programmi più grossi, penalità
molto alta in altre epoche, in cui la RAM era una componente costosa e di bassa capacità.
L'architettura CISC dipende dal compilatore più di quanto non dipenda il RISC: dato che le
istruzioni prevedono più metodi di indirizzamento, e che son presenti istruzioni dalla semantica
complessa, al compilatore viene prospettato un'ampio ventaglio di scelte per quanto concerne
la traduzione di una istruzione, e non sempre la scelta migliore è banale. Come spesso accade
nei problemi di ottimizzazione, la scelta della configurazione migliore è un compito NP
completo, e non è pensabile utilizzare un compilatore che, per ogni istruzione, valuti la scelta
migliore in base al contesto. Si conoscono solo delle buone euristiche, ma il problema
dell'ottimizzazione è un problema di ricerca aperto. La stessa macchina CISC può essere
dunque più o meno veloce rispetto ad una macchina comparabile RISC in base al compilatore
utilizzato.
La vera differenza tra RISC e CISC è la filosofia di funzionamento. In una macchina RISC le
uniche operazioni in grado di accedere alla memoria sono le operazioni di load e di store, tutte
le altre utilizzano solo i registri, mentre in una macchina CISC le operazioni possono accedere
ai registri e alla memoria indifferentemente. Questo non è possibile direttamente, quindi una
macchina CISC quando un'operazione richiede di accedere alla memoria il processore carica il
dato lo salva temporaneamente in un registro (spesso nascosto) esegue le operazioni e poi
salva il risultato in memoria. In sostanza: una macchina CISC mette in piedi un teatro illusorio
per fornire al programmatore un ambiente comodo; una macchina RISC non fornisce questo
teatro illusorio al programmatore dato che questo comunque non programma quasi mai in
assembly e dato che queste operazioni nascoste in realtà rallentano il processore nell'eseguire
le altre operazioni.
6 Architetture superscalari.
Un microprocessore con architettura superscalare supporta il calcolo parallelo su un singolo chip,
permettendo prestazioni molto superiori a parità di clock rispetto ad una CPU ordinaria. Questa
caratteristica è posseduta più o meno da tutte le CPU general purpose prodotte dal 1998.
I microprocessori più semplici sono scalari: compiono una operazione sul numero di operandi di
questa alla volta. Invece, in un processore vettoriale, una singola istruzione viene applicata su di un
vettore, formato da più dati raggruppati. In questo modo, una applicazione che deve eseguire una
certa operazione su una grande quantità di dati viene svolta con molta più rapidità. Un processore
superscalare è una forma intermedia tra i due: istruzioni diverse trattano i propri operandi
contemporaneamente, su diverse unità hardware all'interno dello stesso chip. In questo modo più
istruzioni possono essere eseguite nello stesso ciclo di clock.
Il semplice fatto di eseguire più istruzioni nello stesso ciclo di clock non rende una CPU
superscalare: una CPU con una pipeline semplice, che può quindi caricare un'istruzione, eseguirne
un'altra e immagazzinare il risultato di quella ancora precedente non è necessariamente
superscalare.
In una CPU superscalare sono presenti diverse unità funzionali dello stesso tipo, con dispositivi
addizionali per distribuire le istruzioni alle varie unità. Per esempio, sono generalmente presenti
numerose unità per il calcolo intero (definite ALU). Le unità di controllo stabiliscono quali istruzioni
possono essere eseguite in parallelo e le inviano alle rispettive unità. Questo compito non è facile,
dato che un'istruzione può richiedere il risultato della precedente come proprio operando, oppure
può dover impiegare il dato conservato in un registro usato anche dall'altra istruzione; il risultato
può quindi cambiare secondo l'ordine d'esecuzione delle istruzioni. La maggior parte delle CPU
moderne dedica molta potenza per svolgere questo compito con la massima precisione possibile,
per permettere al processore di funzionare a pieno regime in modo costante; compito che si è reso
sempre più importante con l'aumento del numero delle unità. Mentre le prime CPU superscalari
possedevano due ALU ed una FPU, un processore attuale come ad esempio il PowerPC 970
possiede quattro ALU, due FPU e due unità SIMD. Se il sistema di distribuzione delle istruzioni non
mantiene occupate tutte le unità funzionali del processore, le sue prestazioni ne soffrono
grandemente.
Le architetture superscalari ebbero origine nell'ambiente RISC, dato che questo tipo di design
richiede unità funzionali semplici, che possono essere incluse in più esemplari in una unica CPU.
Questa è la ragione per cui questi processori erano più veloci dei CISC tra gli anni '80 e gli anni '90.
Tuttavia, col progresso della tecnologia, anche design ingombranti come l'IA-32 poterono essere
progettati in modo superscalare.
Attualmente è impensabile un futuro miglioramento sensibile del sistema di controllo, ponendo di
fatto un limite ai miglioramenti prestazionali dei processori superscalari.
4
7 Descrivere l’architettura di una CPU con organizzazione a pipeline. Illustrare
con un esempio le funzioni svolte dai singoli stadi
Pipeline dati Esecuzione delle istruzioni in un microprocessore senza pipeline
IF-ID-EX-MEM-WB
La pipeline dati è una tecnologia utilizzata dai microprocessori per incrementare il throughput,
ovvero la quantità di istruzioni eseguite in una data quantità di tempo.
L'elaborazione di un istruzione da parte di un processore si compone di cinque passaggi
fondamentali:
IF: Lettura dell'istruzione da memoria
ID: Decodifica istruzione e lettura operandi da registri
EX: Esecuzione dell'istruzione
MEM: Attivazione della memoria (solo per certe istruzioni)
WB: Scrittura del risultato nel registro opportuno
Praticamente ogni CPU in commercio è gestita da un clock centrale e ogni operazione
elementare richiede almeno un ciclo di clock per poter essere eseguita. Le prime CPU erano
formate da un'unità polifunzionale che svolgeva in rigida sequenza tutti e cinque i passaggi
legati all'elaborazione delle istruzioni. Una CPU classica richiede quindi almeno cinque cicli di
clock per eseguire una singola istruzione.
. La pipeline dati è la massima parallelizzazione del lavoro di un microprocessore.
Esecuzione delle istruzioni in un microprocessore con pipeline
Una CPU con pipeline è composta da cinque stadi specializzati, capaci di eseguire ciascuno
una operazione elementare
Problematiche
L'implementazione di una pipeline non sempre moltiplica il throughput. L'analisi delle
problematiche legate alla gestione delle pipeline per ottenere le migliori prestazioni teoriche
ricadono sotto la ricerca del instruction level parallelism, il parallelismo a livello d'istruzione, cioè
le istruzioni che possono essere eseguite in parallelo senza creare conflitti o errori di
esecuzione. Comunque le singole pipeline affrontano due problemi principalmente; il problema
legato alla presenza di istruzioni che possono richiedere l'elaborazione di dati non ancora
disponibili e il problema legato alla presenza di salti condizionati.
Il primo problema deriva dal lavoro parallelo delle unità.
e quindi la seconda operazione dovrà bloccarsi per attendere il completamento della prima e
quindi questo ridurrà il throughput complessivo.
Il secondo problema consiste nei salti condizionati.
I programmi contengono delle istruzioni condizionate che se una specifica condizione è
verificata provvedono a interrompere il flusso abituale del programma e a mandare in
esecuzione un altro pezzo di programma indicato dall'istruzione di salto. Ogni volta che questo
accade il microprocessore si trova a dover eseguire un nuovo flusso di operazioni e quindi deve
svuotare la pipeline del precedente flusso e caricare il nuovo flusso. Ovviamente queste
operazioni fanno sprecare cicli di clock e quindi deprimono il throughput. Per ridurre questo
problema le CPU adottano delle unità chiamate unità di predizione delle diramazioni (in inglese
Branch Prediction Unit) che fanno delle previsioni sul flusso del programma. Queste unità
riducono notevolmente i cicli persi per i salti.
8 Tecniche di accesso ai dati in una memoria cache. Illustrare le ragioni per le quali
questo tipo di accesso è critico e come la tecnica set-associative per l’accesso ai
dati di una cache risolva i problemi.
MEMORIA ASSOCIATIVA Memoria tradizionale: (in lettura)restituisce un dato conoscendone la
posizione (indirizzo). Memoria associativa: restituisce unainformazione associata fornendo un dato
TECNICHE ASSOCIATIVE� Il tag viene utilizzato come chiave dilettura� La cache è organizzata
come una memoria associativa Come si è già visto in precedenza la tecnica associativa è molto
costosa quando le dimensioni della memoria crescono
La CPU cache è la cache utilizzata dalla CPU di un computer per ridurre il tempo medio d'accesso
alla memoria. La cache è un tipo di memoria piccola, ma molto veloce, che mantiene copie dei dati
ai quali si fa più frequentemente accesso in memoria principale. Finché la maggior parte degli
accessi alla memoria avviene su dati caricati nella cache, la latenza media dell'accesso alla
memoria sarà più vicina alla latenza della cache piuttosto che a quella della memoria principale..
Ogni locazione di memoria ha anche un indice, cioè un identificatore univoco utilizzato per riferirsi a
quella specifica locazione. L'indice di una locazione in memoria principale è chiamato indirizzo di
memoria. Ogni locazione nella cache ha un'etichetta che contiene l'indice in memoria principale del
dato ivi caricato. Nelle cache dati, questi valori sono chiamati blocchi di cache o linee di cache.
Quando il processore vuole leggere o scrivere in una data locazione in memoria principale,
inizialmente controlla se il contenuto di questa locazione è caricato in cache. Questa operazione
viene effettuata confrontando l'indirizzo della locazione di memoria con tutte le etichette nella cache
che potrebbero contenere quell'indirizzo. Se il processore trova che la locazione di memoria è in
cache, si parla di cache hit (accesso avvenuto con successo), altrimenti di cache miss (fallimento
d'accesso). Nel caso di un cache hit, il processore legge o scrive immediatamente il dato sulla linea
di cache. Il rapporto tra cache hit e accessi totali è chiamato anche hit rate ed è una misura
dell'efficacia della cache stessa.Nel caso di un cache miss, la maggior parte delle cache crea una
nuova entità, che comprende l'etichetta appena richiesta dal processore ed una copia del dato dalla
memoria. Un fallimento del genere è relativamente lento, in quanto richiede il trasferimento del dato
dalla memoria principale, il cui tempo di risposta è molto maggiore di quello della memoria
cache.Alcuni dettagli operativi
Per poter fare spazio a nuovi dati nel caso di un cache miss, la cache generalmente deve eliminare
il contenuto di una delle linee. L'euristica che utilizza per scegliere quale dato eliminare è chiamata
politica di rimpiazzamento. Il problema fondamentale di ogni politica di rimpiazzamento è quello
di dover predire il dato della cache che verrà richiesto nel futuro con minor probabilità. Predire il
futuro è difficile, soprattutto per le cache hardware che devono sfruttare regole facilmente
implementabili in circuiteria, perciò esistono una serie di politiche di rimpiazzamento e nessuna di
esse può essere ritenuta perfetta. Una delle più popolari, la LRU (dall'inglese Least Recently Used,
cioè usato meno recentemente), rimpiazza, appunto, il dato al quale si è fatto accesso meno
recentemente.
Associatività
Quali locazioni di memoria possono essere caricate in quali locazioni della cache
La politica di rimpiazzamento decide dove, nella cache, può risiedere una copia di una particolare
locazione di memoria. Se la politica di rimpiazzamento è libera di scegliere in quale linea di cache
caricare il dato, la cache è chiamata fully associative (o anche completamente associativa). Invece,
se ogni dato in memoria può essere posizionato solo in una particolare linea di cache, essa è detta
direct mapped (o anche a mappatura diretta). La maggior parte delle cache, però, implementa un
compromesso chiamato set associative (o anche parzialmente associativa). Per esempio, la cache
dati di livello 1 dell'AMD Athlon è 2-way set associative, cioè una particolare locazione di memoria
può essere caricata in cache in due distinte locazioni nella cache dati di livello 1.Se ogni locazione
in memoria principale può essere caricata in due locazioni diverse, la domanda sorge spontanea:
quali? Lo schema utilizzato più frequentemente è mostrato nel diagramma a lato: i bit meno
significativi dell'indice della locazione di memoria vengono usati come indici per la cache e ad
ognuno di questi indici sono associate due linee di cache. Una buona proprietà di questo schema è
che le etichette dei dati caricati in cache non devono includere quella parte dell'indice già codificata
dalla linea di cache scelta. Poiché i tag sono espressi su meno bit, occupano meno memoria ed il
tempo per processarli è minore.
determinare quale tra le linee esistenti è stata usata meno recentemente, in quanto la nuova linea
entra in conflitto con differenti "set" di linee per ogni "way"; il tracciamento LRU è infatti
normalmente calcolato per ogni set di linee.
L'associatività è un compromesso. Se ci sono dieci posizioni, la politica di rimpiazzamento può
riempire una nuova linea, ma quando bisogna cercare un dato devono essere controllate tutte e 10
le posizioni. Controllare più posizioni necessita di più potenza, area e tempo. D'altra parte, le cache
con più associatività soffrono di meno cache miss (vedere anche più in basso). La regola di
massima è che raddoppiare l'associatività ha circa lo stesso effetto sull'hit rate che il raddoppio
della dimensione della cache, da 1-way (direct mapping) a 4-way. Aumenti dell'associatività oltre il
4-way hanno molto meno effetto sull'hit rate e sono generalmente utilizzati per altri motivi (vedere il
virtual aliasing, più in basso).
5
9 Spiegare la necessità di utilizzare arbitri per la gestione di interruzioni multiple.
Illustrare un esempio di soluzione.
a.
b.
Descrivere i meccanismi di gestione delle interruzioni. Come
vengono gestite le interruzioni che si presentano
“contemporaneamente” alla CPU ? Come viene gestito
l’annidamento delle interruzioni ?
Tecniche per la gestione di interruzioni multiple.
La gestione di interruzioni multiple avviene utilizzando il meccanismo di annidamento
immagazzinando nello stack gli indirizzi di ritorno e i relativi contesti. Si possono verificare
problemi se è in fase di esecuzione una attività con caratteristiche stringenti di tempi di servizio
e se l’interruzione di tale unità non è possibile. Pertanto è necessario un meccanismo che
impedisca le interruzioni quando non sono opportune: in particolare tutte le richieste di
interruzione vengono ignorate, ad ogni richiesta è associata una urgenza (o priorità) e alla CPU
giunge la sola richiesta a priorità maggiore. La CPU può anche decidere di accettare solo (in
ogni istante) le richieste di interruzione con urgenza (o priorità) superiore ad un dato livello.
In generale più periferici possono richiedere interruzione.
La gestione delle interruzioni può anche essere di tipo centralizzato ovvero tutte le richieste
sono gestite da un solo modulo che emette un vettore (codice) corrispondente alla richiesta
d’interruzione che il modulo di controllo ritiene a priorità maggiore. Tale vettore è specifico per
ogni periferica che può richiedere l’interruzione. E’ come se la CPU costruisse un’istruzione di
call di cui l’hardware gli passa parte dell’indirizzo. In un sistema modulare a bus non è possibile
utilizzare molte linee dedicate. Nel caso di gestione distribuita la selezione del periferico
avviene con polling e vettorizzazione. Nel caso del polling ogni elemento periferico dispone di
un registro che contiene un bit che segnala la richiesta di interruzione e una sola routine di
gestione legge in sequenza tutti i registri. Nel caso della vettorizzazione ogni periferico invia alla
CPU un valore o vettore identificatore. Il vettore viene utilizzato per individuare il programma
opportuno di gestione dell’interruzione.Se più periferici chiedono contemporaneamente
interruzione, occorre stabilire chi servire per primo applicando regole di arbitrazione che
possono essere di tipo concentrato o distribuito.. La gestione di interruzioni multiple avviene
utilizzando il meccanismo di annidamento immagazzinando nello stack gli indirizzi di ritorno e i
relativi contesti.
NTERRUPT
• Evento infrequente ed eccezionale.
• Generato internamente o esternamente.
• Causa il trasferimento del controllo a un programma specifico di servizio dell'evento.
L’interruzione è utilizzata per la gestione degli apparatidi I/O. Per ottenere risposte rapide nella
gestione didischi, tastiere (keyboard), modem, ...
Questi elementi devono richiamare l'attenzione della CPU molto rapidamente e il trasferimento
dei dati da e verso gli questi organi deve avvenire nel modo più
efficiente possibile.
E’ necessario assegnare urgenze o priorità diverse alle
varie richieste di intervento se contemporanee.
INTERRUPT ESTERNI
Gestione di I/O mediante interrupts:
• La CPU non deve verificare con continuità lo stato
dei dispositivi di I/O.
• Accesso diretto e rapido alla CPU per:
• richiesta inizio operazione.
• segnalazione di fine operazione.
INTERRUPT INTERNI
Provenienti dall'interno della CPU in condizioni
particolari (traps):
• errori (divisione per 0, overflow).
• malfunzionamenti hardware (errori di trasferimento
dati sul bus).
GESTIONE INTERRUPT
• La presenza di un interrupt è segnalata alla CPU da
una linea proveniente dall'esterno
• Il segnale viene memorizzato è testato dalla CPU
alla fine di ogni ciclo di istruzione
• La CPU risponde trasferendo il controllo a un altro
programma
• A cura della CPU (polling).
• A cura dell'elemento che genera interruzione.
• La CPU ottiene l'indirizzo di memoria del programma
di servizio:
• Al termine della fase di polling.
• Durante la stessa richiesta di interruzione.
• Il PC e altre informazioni essenziali (contesto)
relative alla CPU vengono memorizzate
automaticamente.
INTERRUZIONI MULTIPLE
• La gestione di interruzioni multiple avviene
utilizzando il meccanismo di annidamento.
• Gli indirizzi di ritorno e i relativi contesti possono
essere immagazzinati nello stack.
10 Accesso diretto alla memoria. Illustrare l’architettura del modulo e i vantaggi di questa
soluzione.
Accesso Diretto alla Memoria (DMA)
Si è visto nelle sezioni precedenti come sia necessario sincronizzare l'accesso della CPU ai
dispositivi esterni (periferiche). In particolare si sono analizzate le due tecniche di polling e di
interrupt, e si è visto come la seconda tecnica consenta un utilizzo più efficiente della CPU
specialmente quando il dispositivo è significativamente più lento della CPU. Se il dispositivo è più
veloce, la tecnica ad interrupt pone dei limiti alla velocità di trasferimento dei dati. Una terza
metodologia consente il trasferimento dei dati tra la periferica e la memoria senza il coinvolgimento
diretto della CPU, se non per l'inizializzazione e la terminazione del trasferimento. Tale tecnica
prende il nome di Direct Memory Access (DMA).
La gestione del DMA richiede un modulo di controllo esterno alla CPU (anche se spesso montato a
bordo dello stesso chip), collegato alla periferica ed al bus di comunicazione. Tale dispositivo, detto
DMA controller, consente l'impostazione tramite un insieme di registri di configurazione visibili dalla
CPU. Di questi registri, sono comuni a tutti di DMA controllers il registro CAR (Current Address
Register) ed il egistro WC (Word Count). Per impostare un trasferimento DMA la CPU provvede ad
inizializzare tali registri: il registro CAR viene impostato all'indirizzo iniziale in memoria del blocco di
dati da essere trasferito (sequenziale in memoria) , ed il registro WC al numero di elementi da
trasferire. Una volta iniziato il trasferimento DMA (normalmente tramite la scrittura di un apposito
codice nel Command Register del DMA controller), il controllore DMA provvederà autonomamente
al trasferimento dei dati da o per la memoria, non appena la periferica collegata (ed
opportunamente programmata dalla CPU) sia disponibile.
Si osservi che la periferica risulterà collegata al DMA controller per lo scambio dei dati, ma anche al
bus di comunicazione per la programmazione da parte della CPU (tipicamente attraverso un
insieme di registri visti come locazioni di memoria in un'architettura memory mapped).
Quando il DMA controller è pronto a trasferire uno o più dati deve richiedere l'accesso al bus di
comunicazione, normalmente utilizzato dalla CPU. L'arbitraggio del bus deve avvenire in maniera
controllata per evitare conflitti tra CPU e DMA controller. Per questa ragione i bus di
comunicazione normalmente prevedono un protocollo ed alcune linee di controllo per l'arbitrazione
del bus. In ogni momento tra i dispositivi collegati al bus è definito un singolo Proprietario del bus
(Bus Master). Normalmente il Bus master è la CPU, ma un altro dispositivo può richiedere di
diventare il Bus Master. Questo è il caso del DMA controller quando questi deve trasferire uno o più
dati. Il dispositivo richiedente segnalerà la richiesta al bus Master corrente tramite una linea di
controllo (Bus Request), ed il Master corrente segnalerà la cessione del bus tramite un'altra linea di
controllo (Bus Grant). A questo punto il DMA controller ha il possesso del bus e potrà utilizzare il
bus per il trasferimento dei dati da o per la memoria, fino a che il bus non venga nuovamente
richiesto dalla CPU o da un altro dispositivo. Ad ogni trasferimento, il DMA controller modificherà il
registro CAR che ora punterà al successivo dato da trasferire in memoria, e decrementerà il
registro WC. Quando il contenuto del registro WC diventa zero, tutti i dati impostati sono stati
trasferiti.
Quando non è il bus Master, la CPU può procedere con le operazioni interne che non richiedano un
accesso al bus. Si noti che la presenza della cache consente alla CPU di procedere anche con
operazioni di accesso alla memoria a patto che queste generino uno Hit nella cache. Al primo Miss,
la CPU dovrà richiedere nuovamente l'accesso del Bus per il trasferimento dei dati con la memoria.
Si osservi che durante un trasferimento DMA di un blocco di dati il bus può essere scambiato più
volte tra la CPU ed il DMA controller. Tale meccanismo è tuttavia gestito completamente
dall'hardware, e risulta quindi completamente trasparente al programma.
L'impatto del trasferimento DMA sulla performance della CPU risulta limitato alle possibili
contenzioni sul bus, ovvero alla possibile attesa richiesta alla CPU per riprendere possesso del
bus. In un sistema opportunamente equilibrato, tale riduzione di performance risulta assai limitata,
per cui il trasferimento DMA risulta quasi trasparente all'esecuzione normale della CPU.
Poiché il trasferimento dei dati in DMA procede autonomamente dal flusso di esecuzione del
programma, occorre un meccanismo per notificare la CPU dell'avvenuto trasferimento del blocco di
dati. Tale notifica avviene tramite un opportuno interrupt generato dal DMA controller quando il
trasferimento del blocco impostato è terminato. La routine di servizio associata intraprenderà le
azioni necessarie per la notifica del trasferimento avvenuto.
E' normalmente il sistema operativo che gestisce il trasferimento DMA per dispositivi quali i dischi
magnetici o le schede di rete, ed in generale per tutti quei dispositivi caratterizzati da un'alta
velocità di trasferimento.
6
12 Gestione I/O a controllo di programma
11 Sistemi a BUS Ingresso e Uscita
Lo spostamento dei dati tra moduli e l’acquisizione di dati dall’esterno è uno degli aspetti più
critici di un sistema di elaborazione influenzando in modo particolare prestazioni, costi,
modularità e standardizzazione. Esistono diverse tipologie di trasferimento, di seguito
analizzeremo le principali. • Trasferimento dati punto a punto. Abbiamo due attori del sistema
che sono la sorgente e la destinazione. Il segnale di strobe comanda la memorizzazione del
dato, la cui trasmissione avviene in modo diretto. Il trasferimento punto a punto richiede un solo
segnale di strobe per segnalare all’elemento ricevente la presenza del dato corretto e dunque il
fatto che va’ immagazzinato. Trasferimento a diffusione. Si definisce tale in quanto
potenzialmente tutte le destinazioni possono vedere l’informazione trasmessa dalla sorgente in
quanto sono tutte collegate ad uno stesso BUS. Tuttavia ogni destinazione è pilotata dal proprio
segnale di strobe. In questo tipo di logica uno stesso elemento invia dati a più destinazioni.
Trasferimento a collettore. Più elementi possono inviare dati a un destinatario. Non è possibile
che più sorgenti trasmettano contemporaneamente altrimenti genererebbero conflitti si accesso
sul BUS. Dunque, il canale di trasferimento viene utilizzato per un solo trasferimento per volta.
In tale logica ogni sorgente avrà un segnale di output enable che regolerà la possibilità o meno
di trasmettere. Arbitro centralizzato che fornisce la possibilità di modificare agevolmente la
politica di assegnazione e che presenta maggior osservabilità ovvero si può facilmente sapere
cosa sta succedendo in quanto tale informazione risiede in una sola fonte (l’arbitro appunto). La
politica delle priorità è contenuta all’interno dell’allocatore che risponde sempre con una sola
concessione. L’unità di controllo risponde con un solo grant in base alle priorità. All’interno
dell’allocatore è definita la politica di assegnazione delle risorse. Vediamo dunque due possibili
versioni dell’allocatore concentrato La differenza fra i due circuiti sta nel fatto che crescendo di
numero di moduli che richiedono l’accesso, nel primo caso serviranno porte con sempre più
ingressi, mentre nel secondo caso ci si limita ad allungare la catena. Nel primo caso ci sono i
problemi di costo e complessità dovuti a porte con n ingressi, mentre nel secondo le
problematiche risiedono nei tempi di propagazione che si allungano. Arbitro distribuito che
fornisce maggiore modularità e possibilità di espansione e riconfigurazione e inoltre migliore
tolleranza ai guasti. Il circuito dell’arbitro distribuito è uguale a quello concentrato, varia la
distribuzione delle parti hardware. Se voglio variare la priorità posso sfruttare dei meccanismi
ad anello anche se in realtà si tratta di una struttura prevalentemente fissa. o Esistono alcune
tecniche di arbitrazione (a distribuzione decrescente): a catena o daisy-chain, polling, a
richieste indipendenti. Il ciclo di acquisizione del controllo del bus è gestito da un arbitro e
avviene con una sorta di meccanismo di handshake. Polling. In questo caso, in corrispondenza
di una richiesta il modulo di controllo genera una sequenza di indirizzi corrispondenti alle varie
unità. Il modulo indirizzato con una richiesta pendente assume il controllo. L’unità interroga in
sequenza i vari moduli tramite la generazione di indirizzi. Il vantaggio è che la priorità non è più
statica (fisica), ma è determinata dal modo in cui l’unità di controllo genera indirizzi, o meglio,
l’ordine con cui li emette e che quindi è gestibile via software.
Vediamo ora la struttura di una generica porta d’ingresso. Nella forma minima richiede solodei
buffer. Il sistema in figura è in grado di gestire delle uscite a tre stati grazie alla regione
difunzionamento in alta impedenza.Se pensiamo alla connessione contemporanea ad uno stesso
DBUS di dispositivi come questo cirendiamo immediatamente conto che è vietato collegare le
uscite in quel modo. Tuttavia grazie allagestione a tre stati è possibile avere tali tipi di
configurazioni, questo perché sfruttando la zona di alta impedenza dei dispositivi si ha come una
sorta di interruttore interno che viene aperto nel momento in cui il dispositivo deve essere abilitato;
in questo modo solo un dispositivo sarà acceso contemporaneamente e questa risulta essere una
configurazione lecita. Vediamo ora un semplice schema di porta d’uscita che nella sua forma
minima richiede solo dei latch. All’interno dell’architettura di sistema avremo che le varie unità
periferiche dialogheranno con la cpu attraverso delle opportune interfacce che trasmetteranno dati
su dei bus (bus indirizzi e bus dati) e delle linee di controllo. I dispositivi procedono in modo
asincrono rispetto alla CPU e dunque serve un’interfaccia che consenta il dialogo e che dunque
dovrà fornire: un registro per i dati trasferiti, un registro per i co andi della periferica ed un registro
per lo stato della periferica. L’interfaccia svolge dunque la funzione di adattamento sia elettrico sia
logico tra le unità periferiche e il calcolatore. Ricordiamo che un registro è una locazione con un
determinato indirizzo a cui la CPU può accedere in lettura e/o scrittura. Dunque ad ogni registro è
associato un indirizzo il cui riconoscimento determina la selezione del relativo registro; si utilizza il
termine porta. Vediamo dunque lo schema di un’interfaccia. In figura sono rappresentati il registro
dati, quello di stato e quello di controllo; in particolare le frecce indicano la direzione del flusso
informativo. Si osservi che solo il registro dati presenta un flusso bidirezionale Nella gestione a
controllo di programma, vi è una sorta di routine che diventa una componente software che
nasconde al suo interno la gestione della periferica. Si tratta di una specie di dispositivo che svolge
una determinata funzione. Tuttavia con questo tipo di metodologia nessun altra attività viene svolta
dal processore, se non quella di osservare lo stato della periferica; dunque il tempo di CPU è
totalmente sprecato nell’attesa. Si pensi ad esempio ad una routine che gestisca un dispositivo di
stampa in cui la CPU (ordine di 100M istr/s) attenda la stampa di ogni singolo carattere ovvero irca
10ms. Tra carattere e carattere la CPU avrebbe tempo per eseguire 10.000 istruzioni. Dunque con
la gestione a controllo di programma si viaggia alla velocità del dispositivo periferico. Vediamo un
semplice schema di interfaccia d’uscita.
7
13 CLUSTER
Per cluster si intende una classe di architetture di elaborazione parallele basate su un insieme
di
elaboratori indipendenti, cooperante per mezzo di una rete di interconnessione e coordinato
mediante un sistema operativo che lo rende in grado di operare su di un singolo workload. Il
commodity cluster è costituito da nodi di elaborazione commerciali (COTS – Commercial off the
shelf) in grado di operare in modo indipendente e collegati tramite una rete di interconnessione
(LAN o SAN) anch’essa di tipo COTS. Un cluster può essere utilizzato in molti modi come ad
esempio ottenere elevate prestazioni su di un singolo problema, elevato throughput o elevata
capacità con un carico di lavoro a processi, elevata disponibilità mediante la ridondanza dei
nodi, elevata banda ottenuta dalla molteplicità dei dischi o dei canali di I/O. Gli aspetti che
giustificano l’interesse così forte per i sistemi a cluster sono sicuramente il buon rapporto
prestazioni/prezzo e il rafforzamento del ruolo personale. Nel primo caso, i commodity cluster
possono migliorare il rapporto prestazioni/prezzo di un ordine di grandezza rispetto ad
architetture diverse (circa 1 euro per Mflop). I sistemi cluster ad elevate prestazioni, utilizzano
moduli elementari che derivano dai sistemi di uso personale. L’amministrazione HW e SW
richiedono competenze maggiormente disponibili sul mercato. Si ha un maggior senso di
controllo del sistema e della sua evoluzione. Gli elementi su cui si basano i cluster (nodi di
elaborazione e sistemi di rete) sono disponibili sul mercato spesso per uso personale.
L’integrazione non richiede dunque moduli specializzati e i costi sono ridotti. Per la prima volta
utenti e venditori hanno a disposizione un’architettura parallela stabile e indipendente. Questo
garantisce persistenza a lungo termine nell’architettura e giustifica investimenti software.
14 I Sistemi di Memoria
I sistemi di memoria di un elaboratore possono essere divisi in tre tipologie: memoria interna
al processore, memoria principale e memoria secondaria. Ogni tipologia di memoria differisce in
termini di tecnologie costruttive, prestazioni, prezzo ecc.
La memoria interna costituisce sostanzialmente la parte dei registri interni alla CPU (visibili o
no al programmatore) che memorizzano temporaneamente dati ed istruzioni. Le prestazioni devono
dunque essere molto elevate, a tal proposito la memoria interna ha tempi di accesso dell’ordine di
qualche nano secondo. Infine, a causa dei costi molto elevati le dimensioni sono nell’ordine di
decine
di bytes. Volendo citare una piccola nota storica, la prima macchina dotata di cache è l’Intel 486.
La memoria principale è quella che viene utilizzata per memorizzare i programmi che la CPU
esegue e i dati cui la stessa CPU può accedere direttamente (è importante notare che a questo tipo
di
memoria la CPU accede direttamente). Si tratta di una memoria veloce e di grande capacità in
genere
intorno alle centinaia di MBytes. Di solito sono dispositivi ad accesso casuale.
La memoria secondaria viene impiegata per memorizzare dati e istruzioni che non sono di
immediato interesse della CPU. Si tratta di una memoria di grandi dimensioni (GBytes) e molto più
lenta della memoria RAM, all’incirca i suoi tempi di accesso sono di 6 ordini di grandezza più lenti.
Dal punto di vista dei costi poi è due ordini di grandezza meno costosa della RAM. La memoria
principale può essere divisa in memoria in linea (dischi magnetici) e memoria fuori linea (nastri
magnetici, cd, dvd). Di solito sono dispositivi ad accesso misto.
I vari tipi di memoria sono realizzati con tecnologie diverse a seconda di costo per singolo bit
immagazzinato, tempo di accesso e modo di accesso (seriale o casuale). E’ importante notare che
il
tempo di accesso è il ritardo fra l’istante in cui avviene la richiesta e l’istante in cui il dato è
disponibile
al richiedente. Nel corso degli anni, seppur le prestazioni della memoria siano migliorate
notevolmente,
i tempi di accesso non si sono discostati così tanto dai valori precedenti. Ma vediamo in dettaglio
alcune di queste tecnologie.
Le memorie a semiconduttore sono realizzate su un circuito integrato che grazie alla tecnologia
VLSI è in grado di fornire capacità sempre crescenti. In ogni circuito integrato sono contenute le
celle
di memoria, i circuiti di decodifica dell’indirizzo e l’interfacce di uscite di potenza (buffer) e i circuiti
di ingresso. Lo schema di tale memoria può essere riassunto nella figura seguente:
8
15 arbitrio concentrato arbitrio distribuito
Arbitro centralizzato che fornisce la possibilità di modificare agevolmente la politica di
assegnazione e che presenta maggior osservabilità ovvero si può facilmente sapere cosa sta
succedendo in quanto tale informazione risiede in una sola fonte (l’arbitro appunto). La
politica delle priorità è contenuta all’interno dell’allocatore che risponde sempre con una
sola concessione. L’unità di controllo risponde con un solo grant in base alle priorità.
All’interno dell’allocatore è definita la politica di assegnazione delle risorse. Vediamo
dunque due possibili versioni dell’allocatore concentrato
La differenza fra i due circuiti sta nel fatto che crescendo di numero di moduli che
richiedono l’accesso, nel primo caso serviranno porte con sempre più ingressi, mentre nel
secondo caso ci si limita ad allungare la catena. Nel primo caso ci sono i problemi di costo e
complessità dovuti a porte con n ingressi, mentre nel secondo le problematiche risiedono nei
tempi di propagazione che si allungano.
• Arbitro distribuito che fornisce maggiore modularità e possibilità di espansione e
riconfigurazione e inoltre migliore tolleranza ai guasti. Il circuito dell’arbitro distribuito è
uguale a quello concentrato, varia la distribuzione delle parti hardware. Se voglio variare la
priorità posso sfruttare dei meccanismi ad anello anche se in realtà si tratta di una struttura
prevalentemente fissa Esistono alcune tecniche di arbitrazione (a distribuzione decrescente): a
catena o daisy-chain,
polling, a richieste indipendenti. Il ciclo di acquisizione del controllo del bus è gestito da un
arbitro e
avviene con una sorta di meccanismo di handshake.
STRATEGIA DI SOSTITUZIONE DELLE PAGINE
FIFO (First-In-First-Out)
Primo arrivato primo servito. Si sostituiscono le pagine in memoria da più tempo.
LRU (Least Recently Used)
Sostituzione della pagina usata meno recentemente. Si sostituiscono quelle pagine che è da più
tempo in memoria senza
essere stata referenziata. Il sistema aggiorna la coda ogni volta che una pagina viene referenziata.
FIFO seconda chance e sostituzione a orologio(First-In-First-Out)
Si sostituiscono le pagine in memoria da più tempo. La seconda ch’ange consiste nell’avere anche
un bit di referenza.
Se il bit è posto a 1 significa che la pagina è stata referenziata ed allora si rimette in coda e si
azzera il bit di riferimento.
In questo modo le pagine referenziate spesso rimangono in memoria.
Last Recent Used (LRU): i riferimenti alle pagine disponibili (pin_count=0) vengono
inseriti in una coda (L.I.F.O.) e prelevati, all’occorrenza, dalla testa. Con questa politica
vengono sostituite le pagine disponibili da più tempo.
I page fault si verificano quando è richiesta una pagina non presente in memoria.
Se tutta la memoria è in quel momento occupata da pagine precedentemente
caricate, è necessario sostituirne una con quella richiesta. La politica LRU sceglie
come candidata alla sostituzione quella che non è stata riferita da più lungo tempo,
con la politica FIFO quella che è stata caricata da più lungo tempo.
9.4.2 Algoritmo di
rimpiazzamento FIFO
• Come pagina vittima sceglie quella arrivata da più tempo in
MP (non c’è bisogno di associare a ogni pagina il tempo di
arrivo, ci basta una coda FIFO)
• E’ in idea semplice, ma non necessariamente buona, infatti:
– se la pagina contiene del codice di inizializzazione del
processo, usato solo all’inizio OK, non servirà più.
– ma se la pagina contiene una variabile inizializzata
all'inizio e usata per tutta l’esecuzione del codice: KO!
9.4.4 Algoritmo di rimpiazzamento
LRU (Least Recently Used)
• Cerca di approssimare OPT sostituendo la pagina che
non è stata usata da più tempo
• Rispetto a OPT, guarda all'indietro anziché che in avanti:
almeno il passato lo conosciamo!
• LRU è un buon algoritmo di rimpiazzamento, perché si
avvicina più a OPT che a FIFO,
ma è difficile da implementare in modo efficiente
9
Scarica