Sei sulla pagina 1di 10

GERARCHIE DI MEMORIA E ARCHITETTURA CON CACHE

Gerarchie di memoria nei sistemi informatici: Diremo che esiste una gerarchia di memoria, nella quale al
livello più alto stanno i dispositivi di memoria più capaci, più lenti e meno costosi. Man mano che si scende
di livello nella gerarchia, i supporti hanno capacità sempre più piccola, tempo di acceso sempre più basso e
costo per bit sempre più grande. Obiettivo del progettista di una gerarchia di memoria è di ottimizzare il
rapporto prestazioni/costo agendo sugli spostamenti di dati tra livelli.

Gerarchie di memoria con paginazione:


Consideriamo due livelli contigui, M1 e M2, nella gerarchia di memoria, con M2 livello più alto. Ad esempio,
nella gerarchia “memoria virtuale - memoria principale” M 2 è la memoria virtuale (fisicamente allocata su
memoria secondaria, ma da non confondere logicamente con essa) e M 1 è la memoria principale, mentre
nella gerarchia “memoria principale – memoria cache” M 2 è la memoria principale e M 1 la memoria cache.
Il sistema genera indirizzi appartenenti a M 2; questi vengono tradotti in indirizzi di M 1 se l’informazione
riferita in M2 è attualmente allocata in M 1, altrimenti viene generata un’eccezione che provoca la
riallocazione di M1.
Il metodo che sta alla base della maggior parte delle applicazioni del concetto di gerarchia di memoria è
quello della paginazione. Lo spazio di M1 e quello di M2 vengono pensati come suddivisi in blocchi, o pagine,
di ampiezza fissa composti di informazioni a indirizzi contigui.
D’ora in poi indicheremo con
• γ la capacità complessiva di uno spazio di memoria, con
• σ l’ampiezza di una pagina nella gerarchia di memoria considerata, e con
• ν = γ/ σ il numero di pagine componenti quello spazio di memoria nella gerarchia considerata
La pagina è considerata come l’unità di informazione del trasferimento tra M 2 e M1 e della rilocazione da
indirizzi di M2 a indirizzi di M1

Paginazione a domanda: Nel metodo detto della paginazione a domanda, quando, nel tentativo di tradurre
un indirizzo n di M2, viene generato un fault (miss), allora l’intera pagina che contiene inf[n] viene trasferita
da M2 a M1 provocando il rimpiazzamento di una pagina già presente in M 1. L’efficacia di questo metodo si
basa su due proprietà dei programmi che, statisticamente, si verificano di frequente:
 la località, o località temporale, secondo la quale i riferimenti generati da un processo tendono ad
accentrarsi, in ogni istante, in gruppi relativamente piccoli di indirizzi tra loro vicini, e tali gruppi tendono a
cambiare in modo relativamente lento e intermittente (=accedere non solo a quel dato in memoria ma
anche a quello immediatamente prima e dopo);
 il riuso, o località spaziale, secondo la quale, nel corso dell’esecuzione di un processo, questo tende a
riferirsi più volte a certe locazioni (cicli iterativi, procedure, riassegnamenti di una variabile, oggetti).
In tal modo, una volta che una pagina è stata trasferita in M 1, questa tende a essere riferita più volte.
Statisticamente, se in M1 è presente un numero sufficientemente alto di pagine di M 1 (insieme di lavoro,
WS: working set), la probabilità che si generi un fault (probabilità di fault, o miss ratio) può essere
mantenuta a un valore basso a piacere. Inoltre, le proprietà di località e riuso vanno d’accordo con le
proprietà di molti dispositivi di memorizzazione dal punto di vista dell’ottimizzazione del tempo di
comunicazione di blocchi di informazione.
Un modello spesso valido è quello secondo il quale il tempo di comunicazione di k informazioni elementari
(parole, byte) è esprimibile come: Tcom = Tsetup + kTtrasm, dove Ttrasm è il tempo di latenza per trasmettere
una singola informazione elementare, e T setup è un ritardo costante di “overhead” necessario per
inizializzare il trasferimento. Secondo

Usiamo euristiche LRU (Last Recently Used): se ho bisogno di spazio allora cerco di eliminare l’informazione
acceduta meno di recente. Infatti se in Cache possiamo memorizzare 2 tipi di accessi, su ad esempio 3.
Memorizziamo per esempio i primi due e man mano sostituiamo il meno recente con quello nuovo
Definizione di WS: {blocchi di M (σ)} che se stanno in cache minimizzano il numero di fault.
RICORDIAMO: M – C – MMU – P
1
- M: contiene tutte le informazioni del mio processo, è grande, economica, molto capiente e lenta;
è un vettore di informazioni; ci ritrovo sempre la stessa roba
- C: tengo le informazioni del working set,costosa, poco capiente e veloce; più piccola di M e in istanti
contiene informazioni diverse.
Per C serve un modo per far corrispondere ad un indirizzo di M una ed una sola posizione di C: Metodo di
indirizzamento della PAGINAZIONE. Dentro la Cache vogliamo sfruttare tutti e due i principi.

Più la capacità è alta più la curva (secondo grafico) è traslata a dx, poiché consideriamo valori più grandi.

Insieme di lavoro (Working set): In una gerarchia di memoria M2 – M1, l’insieme di lavoro di un programma
(processo) è definito come l’insieme di pagine (blocchi) che, se presenti contemporaneamente in M 1,
rendono minima la probabilità di fault. L’insieme di lavoro va considerato sia in termini di quante pagine
che di quali pagine devono essere possibilmente presenti in M 1 contemporaneamente. L’obiettivo di una
gestione efficiente di una gerarchia di memoria è quello di individuare l’insieme di lavoro e cercare di
mantenerlo in M. A questo scopo, occorre cercare di sfruttare al meglio le proprietà di località e, in
particolare, di riuso di ogni programma.
ES) per array che viene completamente scansionato
#fault = 2 N /σ ||Se è possibile garantire la presenza in cache del Working set

Paginazione non su domanda: Alle volte le prestazioni sarebbero, invece, molto più soddisfacenti se la
paginazione non venisse applicata su domanda, bensì “in anticipo”: dalle proprietà del programma si
comprende come, ogni volta che si trasferisce una pagina, sia utile anticipare subito il trasferimento di una
o più pagine immediatamente successive.
Prefetching: La strategia, detta prefetching, è applicabile se, staticamente, si riesce a comprendere
l’andamento dei riferimenti. Il prefetching delle istruzioni viene, di regola, implementato per default
direttamente a firmware dall’unità cache; quello sui dati, quando si riveli conveniente, viene deciso dal
compilatore annotando le istruzioni di LOAD e STORE con l’opzione “prefetch”.

Allocazione statica e dinamica della memoria principale:


Nel caso di allocazione statica della memoria principale, N (spazio di indirizzamento logico) e M (spazio di
indirizzamento fisico) coincidono. Per essere eseguito, tutto il processo è interamente caricato da memoria
secondaria a memoria principale in un’area nota.
Nel caso di allocazione dinamica della memoria principale, lo spazio M assegnato al processo varia a tempo
di esecuzione sia in posizione sia in quantità. In generale, non tutto N è allocato contemporaneamente in
memoria principale, ma solo una sua parte, possibilmente quella che, istante per istante, permette al
processo di reperire la maggior parte delle informazioni (istruzioni e dati) in memoria principale.

Spazio logico di indirizzamento e memoria virtuale:


Gli indirizzi generati dal processore, durante l’esecuzione di un processo, non sono direttamente indirizzi di
memoria principale (indirizzi fisici), bensì indirizzi logici, cioè indirizzi riferiti a un'astrazione della memoria
del processo, detta memoria virtuale. Questa può essere vista come un array unidimensionale, con indici
(indirizzi logici) a partire da zero fino al massimo necessario per rappresentare il programma o fino al
massimo consentito dall’ampiezza dell’indirizzo logico in bit; per una macchina a 32 bit e con

2
indirizzamento alla parola, la massima ampiezza della memoria virtuale di ogni programma è 4G parole.
L’insieme degli indirizzi logici di un processo è detto il suo spazio logico di indirizzamento.

Il codice eseguibile del processo, generato dal compilatore, è quindi riferito alla memoria virtuale. Il
processore genera indirizzi logici sia per le istruzioni sia per i dati. Quando viene creato e caricato, il
processo viene allocato in una zona della memoria principale, la cui ampiezza e i cui indirizzi non coincidono
(tranne casi particolari) con quelli della memoria virtuale del processo. La memoria principale viene allocata
dinamicamente a ogni processo, contando sul fatto che una copia completa, e integra, del processo è
sempre presente in memoria secondaria. Quando un processo viene allocato (o riallocato) in memoria
principale, viene stabilita una corrispondenza tra gli indirizzi logici della parte allocata e gli indirizzi fisici in
cui viene allocata. Questa funzione, detta funzione di rilocazione o di traduzione dell’indirizzo, è di norma
implementata come una tabella associata al processo (Tabella di Rilocazione), che, come il PCB e altre
informazioni di utilità, fa parte essa stessa della memoria virtuale e verrà allocata essa stessa in memoria
principale.
La funzione di rilocazione viene aggiornata (dalla funzionalità del sistema relativa alla gestione della
memoria principale) ogni volta che l’allocazione del processo viene modificata. Ad esempio, in un certo
istante un processo in esecuzione può avere bisogno di informazioni che non sono attualmente allocate in
memoria principale. Queste verranno copiate da memoria secondaria a memoria principale. In generale, le
nuove informazioni andranno a sostituirne altre “meno urgenti” (dello stesso programma o di altri
programmi); se le informazioni sostituite sono state nel frattempo modificate (scritture in variabili), i loro
valori verranno ricopiati da memoria principale nelle posizioni corrispondenti della memoria secondaria.
Questi spostamenti (riallocazioni) comportano opportune modifiche della Tabella di Rilocazione del
processo (dei processi). Si noti che il file eseguibile, presente in memoria secondaria, è sempre
un’immagine affidabile del processo.
μ(indirizzo logico) indirizzo fisico (a cui andare a cercare quell’informazione). L’indirizzo logico è quello
dato dal processore. I moduli di elaborazione a livello delle applicazioni e a livello del sistema operativo
sono i processi: programmi sequenziali con propria capacità di controllo, eseguibili concorrentemente ad
altri e cooperanti con essi.

---Creazione di processi, caricamento, e commutazione di contesto


Quando un processo Q (tipicamente un processo di sistema) esegue una primitiva di creazione di un
processo R, questa provoca il caricamento di R, cioè il trasferimento di informazioni di R da memoria
secondaria a memoria principale. Quando il processo R viene creato, in memoria principale viene copiato
(da memoria secondaria) anche il suo PCB con il valore che è stato inizializzato a tempo di compilazione.

Paginazione Dinamica (on Demand): è diversa dalla paginazione


statica. Nel sistema che andremo a considerare avremo quindi
INDIRIZZO LOGICO e INDIRIZZO FISICO, paginati. Considereremo
pagine di dimensione 4K. Lo interpretiamo a 2 dimensioni.
Abbiamo visto che la corrispondenza tra indirizzi logici n ϵ N e
indirizzi fisici m ϵ M è, per ogni processo Q, una funzione, detta
funzione di rilocazione del processo, μ Q, che può dare come
risultato l’indirizzo fisico corrispondente, se l’informazione
avente quell’indirizzo logico è attualmente caricata in
memoria principale, oppure un'eccezione di “fault di pagina”
in caso contrario:

Nel secondo caso, la conseguente gestione dell’eccezione provvederà a caricare in memoria la pagina
contenente l’informazione richiesta (inf[n]) prelevandola da memoria secondaria (file contenente la
versione compilata del processo).
La rilocazione dell’indirizzo logico, e l’eventuale gestione dell’eccezione di fault di pagina, sono
completamente invisibili al programma la cui compilazione ha dato luogo al processo. La funzione di
3
rilocazione del processo Q, μQ , viene implementata mediante una tabella, detta Tabella di Rilocazione del
processo, TABRILQ, il cui contenuto è inizializzato a tempo di caricamento/creazione e varia durante
l’esecuzione del processo in seguito all’allocazione dinamica di pagine.

Copio l’Offset dal logico al fisico. Uso l’indirizzo logico IPL per accedere alla posizione nella TABRIL (a destra)
dove è presente un bit di presenza che se a uno indica che la pagina logica i-esima è presente in memoria
principale. Nell’identificatore della pagina di memoria principale vi risiede la pagina logica i-esima nel caso
che il bit di presenza è = 1.
Durante la traduzione dell’indirizzo, attraverso la Tabella di Rilocazione è anche possibile effettuare
controlli di protezione: ad esempio controllare se il processo in esecuzione ha diritto di accedere in lettura o
scrittura, o altre modalità più complesse, alla pagina riferita. Allo scopo, nello schema di TABRIL esiste il
campo “Diritti di Protezione”. In caso di controllo negativo, viene generata un'eccezione di violazione di
protezione. Nello schema di TABR1L è anche indicato il campo “Bit di controllo” contenente un bit per
ricordare se la pagina è stata modificata e informazioni per implementare la politica di rimpiazzamento.
Quest’ultima politica, eseguita dalle funzionalità di gestione della memoria in seguito all’eccezione di fault
di pagina, ha come scopo la scelta della pagina da sostituire. La scelta che mediamente fornisce il risultato
migliore, agli effetti della riduzione della frequenza dei fault di pagina è la LRU (Least Recently Used).
Spesso questa politica viene implementata in modo approssimato, per non essere costretti a usare troppi
bit per contare da quanto tempo una pagina non viene usata; come caso limite, ma adottato in molti
sistemi, si ha la politica NRU (Not Recently Used) implementata mediante un contatore di un solo bit.

MMU: La traduzione dell’indirizzo logico e il controllo di protezione, e l’eventuale generazione di eccezioni


di fault di pagina e di violazione di protezione, sono implementate a hardware-firmware nell’unità MMU
facente parte della CPU. Al processore P non è visibile come avviene la traduzione degli indirizzi, ma deve
comunque essere noto l’esito di ogni accesso in memoria. Come sappiamo tale esito viene esplicitamente
inviato da MMU a P per ogni richiesta di accesso; oltre che un esito “ok” (accesso effettuato con successo),
MMU può restituire le seguenti segnalazioni di eccezione: “fault di memoria virtuale”, “violazione di
protezione”, “guasto di memoria o delle linee di interconnessione”, e altre situazioni anomale.
Per effettuare efficientemente la traduzione dell’indirizzo, MMU deve disporre di risorse hardware
opportune. Non è realistico pensare che, viste le dimensioni, l’intera Tabella di Rilocazione del processo in
esecuzione venga copiata in una RAM veloce all’interno di MMU; d’altra parte, la copia di tale Tabella
allungherebbe inutilmente il tempo di commutazione di contesto e molte entrate con alta probabilità non
verrebbero utilizzate.
Da IPLi a IPFj attraverso μ. Deve farla la MMU per ogni cho/ch1 e per ogni LOAD/STORE.

Per implementare in hardware tale


tabella, una MA (memoria
associativa) di capacità C
(tipicamente, C è dell’ordine di

4
poche decine) è costituita da C registri, ognuno contenente una Chiave, e altrettanti contenenti i
corrispondenti Valori.

5
Le uscite dei registri-chiave sono ingressi di C confrontatori, il cui secondo ingresso è costituito dalla Chiave
Key (Key è il IPLi) con la quale si vuole effettuare la ricerca. Viene quindi effettuato il confronto simultaneo
di Key con tutte le Chiavi in tabella. Se uno dei confronti è positivo, allora l’indice del registro-chiave relativo
fornisce univocamente l’indirizzo della RAM dalla quale leggere il Valore(Key) corrispondente a Key; in caso
di tutti confronti negativi, l’evento negativo viene segnalato attraverso il valore di un bit di Fault. In
generale, per poter aggiornare la tabella, sia la parte Chiave sia la parte Valore sono accedibili anche per
indirizzo. Una parte di Tabella di Rilocazione TABRIL è mantenuta, dinamicamente, nella Memoria
Associativa MA nella PO della MMU (ad esempio, con C = 32). Le Chiavi sono gli identificatori di pagina
logica 1PL, mentre i Valori sono i corrispondenti contenuti TABRIL[IPL] della Tabella di Rilocazione.
Normalmente, si mantengono in MA le entrate di TABRIL usate più di recente: questo permette di rendere
trascurabile la probabilità che l’entrata di interesse non risieda in MA (si tratta di un’ulteriore applicazione
della politica LRU). In caso che venga generato “fault di MA’’, MMU provvede a copiare in MA l’entrata di
TABRIL corrispondente alla pagina logica riferita, sostituendo l’entrata usata meno di recente. Per questa
ragione, all’atto della commutazione di contesto, quando viene posto in esecuzione il processo Q, l
’indirizzo di TABRILQ deve essere comunicato a MMU, che lo mantiene in un suo registro interno. Si verifichi
che, in assenza di “fault di MA”, il ritardo introdotto dalla traduzione dell’indirizzo è un ciclo di clock della
CPU.
 Nei confrontatori entrano i valori del registro IPL e il valore in IPL i (se esce uno 0 vuol dire che abbiamo
trovato un valore corrispondente). I valori uscenti dai confrontatori vengono messi in AND e questo
restituisce il FAULT. Questi valori vengono mandati ad un decodificatore e a un commutatore (a cui
vengono associati i bit di presenza).

//vettore memoria  TABRIL

6
Avviene tutto in un ciclo di clock: abbiamo all’inizio del ciclo tutti i registri disponibili. Dobbiamo aspettare
un t dei confrontatori e se non ho FAULT un t del decodificatore e un t del commutatore.  in un ciclo di
clock posso farlo perché ho implementato una cache associativa
SE FAULT=1 ? IND = IND.TAB.RIL[IPL i] ordiniamo una lettura della memoria
di indirizzo IND

ARCHITETTURA CON CACHE

Struttura della CPU con cache: Nella figura seguente è mostrato lo schema delle interazioni tra MMU,
processore P e memoria cache C all’interno della CPU, rimanendo ancora nel modello elementare di
elaboratore:

Nel caso di successo nella rilocazione dell’indirizzo logico (di memoria virtuale), MMU passa la richiesta con
l’indirizzo fisico (di memoria principale) all’unità cache C. Questa provvede all’ulteriore traduzione da
indirizzo di memoria principale a indirizzo di memoria cache, nel caso che la funzione di traduzione sia
definita; in caso di insuccesso (cache fault o cache miss) ha luogo il trasferimento del blocco di memoria
principale richiesto in uno dei blocchi di C, in generale sostituendone uno già presente scelto mediante un
opportuno algoritmo di rimpiazzamento. Il trasferimento del blocco è, a differenza del fault di memoria
virtuale, del tutto invisibile a P.
Occorre prevedere un metodo per il trattamento delle scritture nella memoria cache:
1. nel metodo Write Back, il blocco modificato viene ricopiato nel livello superiore di memoria solo all’atto
della sostituzione del blocco stesso nel livello inferiore (come nella gerarchia della memoria virtuale -
memoria principale) o alla terminazione del processo;
2. nel metodo Write Through, ogni modifica della cache è effettuata immediatamente e
contemporaneamente anche in memoria principale (ovviamente, questa tecnica non è applicabile alla
memoria virtuale).
I metodi di indirizzamento della memoria cache sono descritti di seguito. Il termine “blocco” viene usato al
posto del termine “pagina”, per non creare confusione quando si consideri contemporaneamente le due
gerarchie MV - M e M - C.

Metodi di indirizzamento della cache: I principali metodi sono chiamati diretto, completamente
associativo, e associativo su insiemi.
- METODO DIRETTO: In questo caso ogni blocco di memoria principale può essere trasferito solo in un
determinato blocco della cache: esiste dunque uno e un solo blocco della cache in cui una certa
informazione può risiedere. Si può scegliere di adottare una semplice funzione di corrispondenza tra

7
blocchi, tipicamente la funzione moduloIn questo metodo dunque la funzione di traduzione dell'indirizzo è
immediata -> l'accesso alla cache è dunque effettuato direttamente. Il sistema dovrà mantenere una
Tabella di Corrispondenza, avente NC posizioni: ogni posizione contiene il valore del TAG corrispondente al
blocco di M effettivamente presente nel blocco di cache individuato da BC. Accedendo a questa tabella per
indirizzo con il valore BC, si confronta il contenuto letto con il campo TAG dell'indirizzo fisico; se il confronto
non è positivo si genera un fault. In questa eventualità, l'algoritmo di rimpiazzamento è banale: il blocco da
sostituire non può che essere quello individuato da BC.
La Tabella di Corrispondenza è realizzata mediante una memoria RAM di registri; nel nostro caso, 8K registri
ciascuno di 16 bit (più i bit di controllo).

L'accesso a tale tabella può essere effettuato in parallelo all'accesso del cache: ne consegue che l'accesso
stesso è completato in un ciclo di clock. Questo è reso possibile dall’adozione di variabili di
condizionamento complesse oppure dalla tecnica del controllo residuo: il bit che indica l’eventuale presenza
di fault è quello che condiziona la scrittura nella memoria cache (se richiesta) e la scrittura nell’interfaccia
verso il processore. Come esercizio, i realizzi in dettaglio l’applicazione di questa tecnica. Con il metodo
diretto, tenendo conto anche della presenza della MMU, il tempo di accesso alla memoria cache, in assenza
di fault, come visto dal processore è: tc = 2τ che rappresenta il minimo valore possibile con il protocollo a
domanda e risposta.
I vantaggi di questo metodo sono la velocità e la semplicità. Per contro esso presenta uno svantaggio, che
può rivelarsi anche molto gravoso, derivante dalla rigidità della legge di corrispondenza: quando occorre
accedere ripetutamente a coppie di informazioni (ad esempio, componenti di due strutture dati) che stanno
in blocchi di M corrispondenti allo stesso blocco di C, il numero di fault risulta molto elevato.

- METODO COMPLETAMENTE ASSOCIATIVO


Questo metodo, a differenza del precedente, offre la massima flessibilità circa la corrispondenza tra blocchi
di M e blocchi di C: ogni blocco di M può risiedere in qualsiasi blocco di C. La parte BM dell'indirizzo fisico
generato è usata come chiave per una ricerca tabellare mediante la quale implementare la funzione di
traduzione dell'indirizzo. Per ragioni di efficienza, tale Tabella di Corrispondenza non può che essere
realizzata con una memoria associativa (nell'esempio, di NC = 8K posizioni): la sua uscita fornisce, se non si
verifica fault, l'identificatore del blocco di C. Per esercizio si ricavi la rete combinatoria che fornisce il valore
di BC a partire dalle uscite della memoria associativa. Tenendo conto anche della presenza della MMU, il
tempo di accesso alla memoria cache, in assenza di fault, come visto dal processore è: tc = 3τ
assumendo che in un ciclo di clock sia possibile la stabilizzazione di un solo componente logico memoria.

- METODO ASSOCIATIVO SU INSIEMI


Questo metodo approssima soddisfacentemente sia la flessibilità del metodo completamente associativo
che la semplicità del metodo diretto. Ogni blocco di memoria principale è fatto corrispondere a un ben
determinato insieme di blocchi della cache, potendo essere però allocato in uno qualsiasi dei blocchi di tale
insieme. Con i dati dell'esempio, la cache è suddivisa in NS = 2K. insiemi di bs = 4 blocchi ciascuno.
Similmente a quanto fatto nel Metodo Diretto, adottiamo la funzione modulo per esprimere la
corrispondenza tra blocchi di M e insiemi di cache; l’identificatore SET dell’insieme dei blocchi di cache è
dato da: SET = BM mod NS
dove BM indica l’identificatore del blocco di M e NS il numero di insiemi di blocchi della memoria cache. Se,
come di regola NS è una potenza di 2, il campo BM dell’indirizzo di M contiene l’informazione SET
8
direttamente nei log2 NS bit meno significativi, mentre i restanti bit di MB, indicati con TAG, TAG = BM div
NS
identificano il blocco di M all’interno dell’insieme di tutti quelli che corrispondono a quel particolare insiemi
di blocchi di C identificato da SET.
Mediante SET si accede direttamente a una Tabella di Corrispondenza avente NS entrate: ogni entrata
contiene, oltre a bits di controllo, i TAG corrispondenti ai blocchi di M che risiedono in quell'insieme di C. I
TAG letti sono confrontati simultaneamente, mediante bs confrontatori, con il campo TAG dell'indirizzo di
M: la loro uscita permette di stabilire sia la presenza o no di fault che l'identificatore B del blocco all'intemo
dell'insieme. La concatenazione di B in mezzo ai campi SET e D dell'indirizzo di M dà luogo all'indirizzo fisico.
Tenendo conto anche della presenza della MMU, il tempo di accesso alla memoria cache, in assenza di
fault, come visto dal processore è: tc = 3τ assumendo che in un ciclo di clock sia possibile la stabilizzazione
di un solo componente logico memoria.
È stato verificato mediante simulazioni ed esperimenti che insiemi di (4 - ) 8 blocchi permettono di ottenere
una probabilità di fault molto vicina a quella del metodo completamente associativo. D'altra parte la logica
necessaria è paragonabile a quella del metodo diretto: occorre essenzialmente una memoria RAM di
registri, un numero limitato di confrontatori e una rete combinatoria che permette di modificare i bit di
controllo in funzione dell'uscita della Tabella di Corrispondenza.

Modello dei costi: Si vuole valutare il tempo di completamento del programma e il tempo di servizio per
istruzione. L'efficienza relativa dell’architettura con cache, ε, è valutata come il rapporto tra tempo di
completamento Tideale in assenza di fault di cache e il tempo di completamento effettivo Tc considerando la
penalità dovuta ai fault Tfault. Il tempo di completamento è valutato come: Tc = Tideale + Tfault
Nella valutazione di Tideale, per il tempo di accesso in memoria va, quindi, utilizzato il tempo di accesso alla
cache tc (come “visto” dal processore).
Tfault si valuta come: Tfault = Nfault * Ttrasf
dove:
- Nfault è il numero medio di fault di cache che hanno luogo durante tutta l’esecuzione dello specifico
programma;
- Ttrasf è il tempo necessario per effettuare il trasferimento di un blocco di cache dal livello superiore alla
cache primaria.
La valutazione di Nfault, è il punto chiave del modello dei costi: occorre determinare l'insieme di lavoro del
programma in base alle proprietà di località e riuso, e determinare e se/come è implementabile.
Ricordiamo che il modello dei costi deve essere utilizzabile dal compilatore, per effettuare scelte
relativamente all’ottimizzazione del programma in base alle strategie messe a disposizione dal livello
assembler e firmware. Dunque, il procedimento deve essere formalizzabile in un algoritmo, eventualmente
un’euristica, in base ad un’analisi statica del programma.
Da Tc si ricavano il tempo di servizio T T = Tc / Nistr dove Nistr è il numero medio di istruzioni eseguite per
completare il programma, e l’efficienza relativa ε = Tideale/Tc

Trattamento e valutazione delle scritture


ESEMPI) P1:: for (i=0; i <N; i++) C[i] = max (A[i], B[i])
P2:: for(i=0; i <N; i++) for(j=0; j <N; j++) C[i][j] = max (A[i],B[j])
Affrontiamo due problemi distinti: 1) se effettuare trasferimento di blocco in caso di fault in scrittura, 2)
l’impatto del metodo di scrittura in memoria sulle prestazioni.
1) Scritture e trasferimento di blocchi:
Nel programma possono esistere alcune strutture dati utilizzate in sola scrittura (cioè, che siano presenti
istruzioni di STORE e che queste operino su indirizzi che non sono utilizzati da istruzioni di LOAD).
In tali casi, in seguito a fault è concettualmente inutile effettuare il trasferimento dei blocchi, essendo
sufficiente allocare il blocco in cache e modificarlo. Gli effetti della valutazione delle prestazioni, nel modello
dei costi per tali strutture si pone: Nfault = 0
NOTE:
9
- Organizzazione di memoria modulare interallacciata: sia m il numero di moduli di M; questi leggono
contemporaneamente altrettante parola a indirizzi consecutivi. T trasf = 2Ttr + σ/m*τM + m*τ facendo si che
vengano richieste σ/m letture di m parole a M e che, in parallelo ad ogni lettura di m parola, in cache
avvengano le scritture delle m parole precedenti.

10