Concetti fondamentali di CACHING CPU e memoria principale CPU

Concetti fondamentali di
CACHING
• 
Funzionamento di base di una cache
• 
Cache Direct-Mapped e Set-Associative
• 
Altri aspetti del sotto-sistema di memoria primaria
1
CPU e memoria principale
•  Lo scambio di dati tra la CPU e la RAM è uno dei punti cruciali per le
prestazioni di un computer.
•  Fin dai primi computer sperimentali degli anni ’40 e ‘50, lo sviluppo
di un modo per memorizzare e rendere velocemente disponibili al
processore le istruzioni e i dati del programma in esecuzione ha
rappresentato una delicata e fondamentale sfida tecnologica.
•  La memoria principale è stata sempre più lenta della CPU, e il gap di
prestazioni si è ampliato nel tempo. In più, il flusso di dati e istruzioni
tra CPU e RAM deve passare attraverso il bus, che introduce ulteriori
ritardi
2
CPU e memoria principale
•  Andamento dei rapporti di prestazione tra CPU e RAM negli anni,
posto a 1 il rapporto di prestazioni nel 1980 (H-P3, Fig. 5.2).
Miglioramento RAM: circa 7% l’anno. Miglioramento CPU: 35%
l’anno fino al 1986, 55% negli anni sucessivi.
3
1
CPU e memoria principale
•  Qui la prestazione è misurata come differenza in tempo tra le richieste
di un processore single core verso la RAM e il ritardo nelle risposte a
queste richieste. É interessante osservare come questa differenza di
prestazioni si sia stabilizzata dopo il 2005 (H-P5, Fig. 2.2), ma in
realtà le cose siano peggiorate…
4
CPU e memoria principale
•  …a causa dell’introduzione dei processori multi-core, che possono
produrre un enorme quantità di richieste verso la RAM.
•  Ad esempio, un Core i7 può generare 2 riferimenti in memoria per
core per ciclo di clock. Con 4 core e un clock di 3,2 GHz, l’i7 può
generare un picco di 25,6 miliardi di riferimenti a dati da 64 bit per
secondo, più 12,8 miliardi di riferimenti ad istruzioni da 128 bit, per
un totale di circa 409,6 Gbyte al secondo!
•  Per contro, con la tecnologia attuale la RAM più efficiente può fornire
un massimo di circa 25 Gbyte di dati/istruzioni al secondo…
5
CPU e memoria principale
•  Dovrebbe essere quindi chiaro che è inutile progettare processori
sempre più veloci e sofisticati, se poi non è possibile reperire in modo
veloce le istruzioni che devono eseguire e i dati su cui tali istruzioni
devono operare.
•  Nei vari datapath che abbiamo visto fin’ora, assumevano la presenza
di una Instruction Memory e di una Data Memory che operavano alla
stessa velocità degli altri componenti della CPU.
•  Questa assunzione corrisponde nella realtà all’esistenza di un
sofisticato sistema di gestione delle informazioni che fluiscono tra
CPU e RAM.
6
2
CPU e memoria principale
•  L’idea fondamentale per cercare di limitare il problema della lentezza
della RAM è di utilizzare una gerarchia di memorie sempre più veloci,
e quindi costose (e quindi meno capaci, anche perché occupano più
spazio), in modo da portare “vicino” alla CPU i dati di cui ha più
immediato bisogno.
•  E’ questa l’idea di base della tecnica del caching, ormai diffusa in
tutte le CPU e le architetture general purpose.
Tecnologia di
memoria
Tempo di accesso
tipico
Costo in dollari per
Gbyte nel 2012
500 ÷ 1000
SRAM
0.5 ÷ 2.5 ns
DRAM
50 ÷ 70 ns
10 ÷ 20
Memorie flash
5000 ÷ 50000 ns
0.75 ÷ 1
Dischi magnetici
5000000 ÷ 20000000 ns
0.05 ÷ 0.1
7
DRAM e SRAM
•  Nota: il termine DRAM (Dynamic RAM) indica la tecnologia con cui
sono costruite le RAM usate nella memoria principale del computer.
•  Il termine SRAM (Static RAM) indica la tecnologia di base con cui
sono costruite le RAM usate nei vari livelli di cache del processore.
•  Le SRAM usano, per memorizzare ogni singolo bit, un circuito di
transistors (di solito 6), che devono essere sempre alimentati.
•  Le DRAM usano un condensatore (controllato da un transistor),
la cui carica indica se il bit corrispondente vale 0 o 1. Ogni pochi
millisecondi viene fatto il refresh della carica del condensatore, che
tende a scaricarsi.
•  Le SRAM quindi occupano più spazio, consumano di più, sono più
complesse e costano di più, ma hanno tempi di risposta più veloci.
8
Viceversa per le DRAM.
DRAM e SRAM
•  In realtà, i diversi livelli di cache possono essere costruiti con
tecnologie leggermente diverse.
•  Le SRAM usate per L1 sono ottimizzate rispetto alla velocità di
accesso, mentre quelle usate per L2 ed L3 sono ottimizzate rispetto
alla capienza di memorizzazione.
•  In più L2 ed L3 risultano più lente di L1 perché sono posizionate
fisicamente più distanti dal punto in cui, all’interno del processore,
incomincia l’elaborazione dell’istruzione o del dato.
•  Più raramente, L3 può essere implementata come DRAM, ma con una
logica di accesso alle celle di memoria più efficiente di quella usata
nella DRAM con cui viene implementata la memoria primaria.
9
3
DRAM e SRAM
•  A grandi linee, le SRAM hanno un tempo di accesso di qualche
nanosecondo, mentre le DRAM hanno tempi di accesso dell’ordine di
qualche decina di nanosecondi.
•  Naturalmente, diverse scelte tecnologiche e implementative possono
modificare leggermente, in meglio o in peggio questi tempi di
accesso.
•  Ma in realtà la grossa differenza tra i tempi di accesso alle
informazioni contenute in una cache e alle informazioni contenute in
memoria primaria sono dovute al fatto che per accedere alla memoria
primaria occorre passare attraverso il bus di sistema, il che può
richiedere diversi cicli di clock (vedremo in dettaglio più avanti)
10
Caching
•  È importante ricordare che lo sfruttamento del concetto di caching non
è limitato alla relazione tra CPU e RAM, ma è fondamentale e si
estende a tutto il sistema di memorie di un computer:
–  I registri fanno da cache per la cache hardware
–  la cache hardware fa da cache per la RAM
–  la RAM fa da cache per l’hard disk (memoria virtuale)
–  l’hard disk fa da cache per supporti magnetici più lenti...
11
Caching
•  L’idea di cache è nata insieme a quella di computer:
•  Ideally, one would desire an indefinitely large memory capacity such
that any particular...word would be immediately available...We are
forced to recognize the possibility of constructing a hierarchy of
memories, each wich has greater capacity than the preceding but
which is less quickly accessible
A. Burks, H. Goldstine, J. von Neumann
Preliminary Discussion of the logical Design of
Electronic Computing Instrument (1946)
12
4
Caching
•  Sebbene l’idea di memoria cache sia vecchia quanto l’idea di
computer secondo lo stile von Neumann, solo alla fine degli anni 60
vengono prodotte le prime CPU commerciali dotate di memoria cache
vera e propria.
•  L’idea di base è nota: una cache è una memoria piccola ma veloce che
contiene una parte delle informazioni in RAM.
•  Se una buona percentuale dei dati e delle istruzioni della memoria di
cui ha bisogno la CPU sono nella cache, l’effetto della lentezza della
RAM sulle prestazioni complessive si riduce enormemente.
13
Caching
•  Le CPU attuali poi, sono dotate di cache separate per dati e istruzioni.
In questo modo, in un datapath pipelined, nello stesso ciclo di clock è
possibile:
–  prelevare una istruzione dalla cache di istruzioni (quella che fino
ad ora avevamo chiamato la Instruction Memory) e
–  leggere/scrivere dei dati (relativi ad un’altra istruzione) dalla cache
di dati (quella che chiamavamo la Data Memory).
•  Instruction e Data memory costitiscono nell’insieme la cache di
primo livello (L1)
•  Tutti i processori processori dispongono poi anche di una cache di
secondo livello (L2), e sono ormai comuni i processori con un terzo
livello di cache (L3, ovviamente)
14
Caching
•  Una tipica gerarchia di memorie in un normale computer
(sopra) e in un dispositivo mobile (H-P5, Fig. 2.1):
15
5
Località della cache
•  L’uso di cache è vantaggioso perché, normalmente, valgono due tipi
fondamentali di località:
•  Località spaziale:
–  Aree di memoria con indirizzi simili a quelli appena usati, saranno
a loro volta usate nell’immediato futuro (ad esempio, le istruzioni
vengono eseguite in sequenza, così come gli elementi di un array
sono letti/scritti in sequenza)
•  Località temporale:
–  Locazioni accedute di recente verranno di nuovo accedute
nell’immediato futuro (e.g. istruzioni e variabili di un ciclo).
16
Funzionamento di base di una cache
•  N.B. per ora ci limitiamo a descrivere operazioni di lettura in RAM.
Vedremo più avanti il caso in cui il dato indirizzato vada modificato
•  Dal punto di vista del funzionamento di una memoria cache, la RAM
viene suddivisa in blocchi di dimensione fissa detti cache lines (o
semplicemente linee) o cache blocks (o semplicemente blocchi).
–  Una linea è formata da un numero prefissato (da 4 a 256, a seconda
delle implementazioni, ma sempre una potenza di 2) di byte
consecutivi della RAM.
•  Le linee sono numerate consecutivamente da 0, così se una linea è
fatta di 32 byte avremo:
–  linea 0: contiene i byte della RAM da 0 a 31
–  linea 1: contiene i byte della RAM da 32 a 63
–  linea 2: contiene i byte della RAM da 64 a 95
17
Funzionamento di base di una cache
•  Ogni linea è anche identificata dal suo indirizzo in RAM: l’indirizzo
in RAM del primo byte appartenente a quella linea. Supponiamo che
gli indirizzi della RAM siano scritti usando m + n bit.
•  Se le linee sono formate da 2n byte, ciascuna linea ha un indirizzo che
ha la seguente forma:
xx…xx00…00
m bit
n bit
•  Il numero di una linea non è altro che il valore rappresentato dagli m
bit più significativi dell’indirizzo della linea una volta tolti gli n bit
meno significativi (il concetto è identico a quello che troviamo nella
paginazione della memoria primaria: infatti pagine e frame hanno
18
anch’essi una dimensione che è una potenza di 2)
6
Funzionamento di base di una cache
•  In ogni istante alcune delle linee della RAM sono anche nella cache
(per ora assumiamo che siano presenti solo le cache di primo livello,
separate per dati e istruzioni, che lavorano (più o meno) alla stessa
velocità della CPU).
•  Quando una word (ad esempio un intero, o una istruzione scritta su 4
byte) viene indirizzata, il sottosistema hardware di indirizzamento
della memoria controlla se questa word sta anche nella cache.
•  Se si, si verifica un cache hit tutto procede normalmente, in quanto la
cache è in grado di lavorare alla stessa frequenza degli altri
componenti del datapath.
•  Se non c’è, si verifica un cache miss: (la linea contenente) il dato
mancante viene prelevata dalla RAM. Se necessario una linea della
19
cache deve essere rimossa per far spazio a quella mancante.
Cache Direct-Mapped
• 
Le cache Direct-Mapped (in italiano: ad indirizzamento diretto)
sono il tipo di cache più semplice. Una cache Direct-Mapped è
formata da 2k entry numerate consecutivamente.
• 
Ogni entry memorizza una linea: 2n byte consecutivi della RAM (di
solito 2n = 32 o 64). E ad ogni entry sono associate due
informazioni:
1.  un bit di validità che ci dice se quella entry contiene
dell’informazione significativa.
2.  un campo Tag che identifica univocamente la linea contenuta in
quella entry della cache rispetto a tutte le linee della RAM
• 
Ad esempio, una cache con 2048 entry da 32 byte ciascuna può
contenere in tutto 2048 x 32 = 64KB di dati (o istruzioni). 20
Cache Direct-Mapped
•  In una cache Direct-Mapped, ogni linea della RAM viene
memorizzata in una entry ben precisa della cache.
•  Quindi, dato l’indirizzo di una word della RAM, c’è una sola entry
della cache che può contenere la linea di cui quella word fa parte.
•  Per stabilire in quale entry della cache cercare una linea che contiene
il dato o l’istruzione indirizzati dalla CPU si usa l’operazione:
(num. della linea in RAM) modulo (num. di entry della cache)
•  Un calcolo che è molto facile e veloce da eseguire a livello hardware
se il numero di entry della cache è una potenza di 2.
21
7
Cache Direct-Mapped
•  Però il PC, una LOAD / STORE, specificano l’indirizzo di una word
(una istruzione indirizzata dal PC, o un dato la leggere o scrivere).
•  Il numero della linea di RAM che contiene quella word è allora dato
dagli m bit più significativi dell’indirizzo della word.
•  E dunque per sapere se quella linea è anche nella cache basta guardare
nella entry specificata dalla formula del lucido precedente.
•  Ma poiché |linee in RAM| > |linee in cache|, è evidente che alla stessa
entry della cache faranno capo più linee di RAM, tutte quelle per cui
(num. della linea in RAM) modulo (num. di entry della cache)
dà lo stesso risultato.
•  Come si fa a sapere se la entry della cache in cui si va a guardare
contiene proprio la linea desiderata?
22
Cache Direct-Mapped
•  (Patterson-Henessy, fig. 5.8).
Come esempio, supponiamo
una RAM suddivisa in 32
linee da un byte ciascuna, e
una cache con 8 entry
(ovviamente da un byte).
•  In quale entry della cache
viene inserita la linea di
indirizzo 01001?
•  01001 mod 1000 = 001. Ma notate che l’entry della cache 001
conterrà anche le linee di indirizzo 00001, 10001, 11001.
•  Cosa distingue fra loro tutte le linee che possono andare nella entry
001 della cache? I due bit più significativi del numero di ciascuna
linea, che possono essere usati per distinguere fra loro tutte le linee
di
23
RAM che fanno capo alla stessa entry della cache.
Cache Direct-Mapped
•  Per cui, quando la CPU vuole leggere la linea numero 01001 dalla
cache, innanzi tutto calcola 01001 modulo 1000 = 001 e scopre che
quella linea, se presente in cache, si trova nella entry 001.
•  Se la entry 001 ha il bit di validità = invalid allora la entry è vuota, e
la linea indirizzata viene prelevata dalla RAM e copiata nella entry
001 della cache. Il bit di validità viene settato a valid e dentro al
campo Tag viene scritto 01.
•  Se invece la entry 001 ha il bit di validità = valid, l’hardware controlla
se il tag della entry 001 corrisponde ai due bit più significativi della
linea di numero 01001.
•  Se c’è corrispondenza la entry 001 della cache contiene la linea
cercata, altrimenti si verifica un cache miss. La linea 01001, prelevata
dalla RAM viene inserita nella entry 001 sovrascrivendo il valore
precedente. Il campo Tag viene aggiornato al nuovo valore 01. 24
8
Cache Direct-Mapped
•  Nel caso generale, le linee hanno dimensione maggiore di un byte, e la
CPU indirizza una word di dimensione inferiore alla linea che
contiene quella word, ma il meccanismo è lo stesso.
•  Supponiamo ad esempio una RAM con indirizzi scritti su 32 bit, linee
da 25 byte, word da 22 byte e una cache da 211 entry.
•  I 32 – 5 = 27 bit più significativi dell’indirizzo di una word
costituiscono il numero della linea che contiene quella word.
•  Di questi 27 bit, gli 11 bit meno significativi vengono usati per
indirizzare una specifica entry della cache, e i restanti 16 bit più
significativi costituiscono il TAG che distingue fra loro tutte le linee
di RAM che fanno capo alla stessa CACHE ENTRY.
TAG (16 bit) CACHE ENTRY (11 bit) WORD (3 bit) BYTE (2 bit)
25
Cache Direct-Mapped
•  Ossia, i 32 bit di un indirizzo di RAM generato dalla CPU (attraverso
il PC o una istruzione di LOAD/STORE) sono così suddivisi:
–  TAG: i 16 bit più significativi dell’indirizzo generato dalla CPU,
usati per distinguere fra loro le linee che fanno capo alla stessa
entry in cache.
–  CACHE ENTRY: gli 11 bit che indicano in quale entry della
cache cercare la linea che contiene il dato/istruzione indirizzato.
–  WORD: i 3 bit con cui distinguiamo fra loro le 8 word contenute
in una linea da 32 byte.
–  BYTE: i 2 bit che possono servire a individuare i singoli byte di
cui è composta ciascuna word.
26
Cache Direct-Mapped
•  Dunque, quando la CPU genera l’indirizzo di una word scritto su 32
bit, , l’hardware estrae gli 11 bit della CACHE ENTRY e li usa per
indirizzare una delle 211 entry della cache
•  Se la entry corrispondente è valida (come indicato dal bit di validità),
vengono comparati il contenuto del campo TAG di quella entry con i
16 bit più significativi dell’indirizzo.
•  Se sono identici, si verifica un cache hit. Attraverso il campo WORD
dell’indirizzo è possibile estrarre dalla linea contenuta in quella entry
della cache la word specificata dall’indirizzo.
27
9
Cache Direct-Mapped
•  In caso di cache miss invece, la linea deve essere prelevata dalla
RAM e copiata nella entry della cache, eventualmente sovrascrivendo
la linea (e il relativo TAG) precedenti.
•  Notate quindi il principio di località temporale: un dato indirizzato più
di recente sostituisce uno più vecchio.
•  Naturalmente, un cache miss produce sempre una perdità di tempo
(leggermente) superiore al tempo necessario a prelevare direttamente
il dato in RAM
•  In ogni caso, perché la cosa sia efficiente tutte le operazioni sono
implementate a livello hardware, e per quanto possibile in parallelo.
28
Cache Direct-Mapped
•  Un esempio cache direct-mapped con 1024 entry e linee da 4 byte.
I 20 bit più significativi vengono usati come tag, i 10 bit intermedi
come numero della linea, e i restanti 2 bit meno significativi per
indirizzare il byte all’interno di ciascuna linea
(Patterson-Hennessy, fig. 5.10)
•  Se dovessimo indirizzare word da
due byte all’interno dellle linee,
quale porzione dell’indirizzo
generato dalla CPU useremmo?
29
Dimensioni di una cache
•  Notate che la dimensione effettiva di una cache è in realtà superiore al
valore dichiarato, in quanto per ogni entry occorre anche memorizzare
il tag della linea memorizzata, e il bit di validità.
•  Consideriamo ad esempio una cache da 16 Kbyte (214 byte = 16384
byte) con 1024 (210) entry (e quindi con linee da 16 (24) byte.
•  Se un indirizzo è scritto su 32 bit, ciascun tag sarà composto da 32 –
10 – 4 = 18 bit, a cui va aggiunto il bit di validità, e quindi ogni entry
è formata da 128 + 19 = 147 bit.
•  In totale la cache deve memorizzare 1024 · 147 = 150528 bit, pari a
18816 byte.
30
10
Dimensione delle linee
•  Le prestazioni di una cache dipendono anche dalla dimensione scelta
per le linee. In generale, linee più grandi consentono di diminuire i
cache miss, perché sfruttano meglio il principio di località spaziale.
•  Tuttavia, oltre una certa dimensione non conviene andare, perché se le
linee sono troppo grandi, una cache di dimensione prefissata ne può
contenere poche, e aumenta la probabilità che una linea debba essere
rimossa dalla cache (perché si è verificato un cache miss) prima che
molti dei dati contenuti in quella linea siano stati usati.
31
Dimensione delle linee
•  La figura (Patterson-Hennessy, 5.11) mostra la frequenza di cache
miss per diverse dimensioni delle linee (sulle ascisse) e cache di
diverse dimensioni nel caso del benchmark SPEC92. Notate come
cache più grandi permettono di utilizzare linee di dimensione
maggiore (oltre ovviamente a produrre un minor numero di cache
miss).
32
Gestione dei cache miss
•  Che succede se si verifica un cache miss? La pipeline deve essere
fermata, in attesa di recuperare dalla RAM il dato o l’istruzione
mancante.
•  Nel caso di cache miss nella Instruction Memory, il PC corrente deve
essere anche decrementato dello stesso valore che gli era stato
aggiunto nella fase IF dell’istruzione mancante.
•  Quando la linea contentente il dato/istruzione mancante è stata
recuperata, l’esecuzione riprende. In caso di istruzione mancante
viene rieseguita la fase IF, in caso di dato mancante per una LOAD,
viene rieseguita la fase MEM
33
11
Gestione delle scritture
•  La gestione delle scritture è più delicata, perché richiede (prima o poi)
la modifica dei dati anche in RAM.
•  In caso di scrittura di una linea della cache, si può scegliere di
propagare immediatamente la modifica anche alla RAM, in modo da
garantire la coerenza della cache.
•  Sempre per mantenere la coerenza della cache, in caso di cache miss
in scrittura il dato mancante viene prelevato dalla RAM, modificato in
cache, e la modificata ripropagata alla RAM.
•  Questo schema di gestione delle scritture in cache prende il nome di
write-through: le scritture vengono sempre eseguite sia in cache che
in RAM, in modo che i dati presenti nelle due memorie siano sempre
consistenti.
34
Gestione delle scritture
•  Lo schema write-through non offre però buone prestazioni, perché
richiede, per ogni scrittura in cache, anche l’accesso alla RAM, una
operazione che consuma molti cicli di clock.
•  Lo schema alternativo al write-through è noto come write-back, in
cui un valore viene modificato solo nella cache (si usa a volte il
termine write deferred).
•  La modifica verrà propagata alla RAM (o ai livelli inferiori di cache,
nei sistemi che ne hanno più di uno) solo se il dato stesso deve essere
rimpiazzato da un altro con cui condivide lo stesso tag.
35
Il supporto della RAM
• 
Il tempo necessario a recuperare un dato in RAM quando si verifica
un cache miss viene normalmente detto penalità da fallimento
(miss penalty).
• 
La durata della penalità da fallimento è dovuta alle tre operazioni
fondamentali necessarie per gestire un cache miss:
1.  Inviare l’indirizzo della linea mancante alla RAM
2.  Accedere alla RAM per recuperare la linea
3.  Inviare alla cache la linea recuperata
36
12
Il supporto della RAM
•  La prima e la terza operazione possono richiedere un ciclo di clock
(attenzione, del bus, non del clock di CPU), mentre la seconda,
richiede di solito molto più tempo, ad esempio dieci o venti cicli del
clock (sempre del bus).
•  Inoltre, una linea della cache è di solito molto più grande della
quantità di dati che un banco di RAM è in grado di fornire ad ogni
accesso.
•  Ad esempio una linea può essere grande 16 byte, mentre con un
accesso alla RAM possiamo leggere in tutto una word da 32 bit, ossia
4 byte, e abbiamo quindi bisogno di 4 accessi per recuperare l’intera
linea.
37
Il supporto della RAM
•  Consideriamo allora un sistema a 32 bit (e quindi con un bus a 32 bit).
Se supponiamo (ipotesi ragionevole) che un accesso alla RAM
richieda 15 cicli di clock (del bus) per leggere una word da 32 bit, per
servire un cache miss con linee da 16 byte impiegheremo:
–  1 ciclo di clock per inviare l’indirizzo della linea mancante alla
RAM
–  4 × 15 cicli di clock per leggere l’intera linea
–  4 × 1 cicli di clock per inviare l’intera linea alla cache
•  Per un totale di 65 cicli di clock (del bus).
38
Il supporto della RAM
•  Possiamo cercare di migliorare la situazione:
–  allargando la banda passante della RAM, ossia la quantità di dati
che possiamo prelevare dalla RAM con un unico accesso
(ad esempio in modo che una intera linea possa essere prelevata
con un solo accesso).
–  Allargando il bus, in modo da poter trasportare in un unico ciclo di
clock (del bus) l’intera linea prelevata dalla RAM al processore.
•  Però aumentare l’ampiezza del bus fino a 16×8 bit trasportati in
parallelo è una soluzione tecnicamente molto costosa e difficile da
realizzare. Del resto, anche il solo ampiamento della banda passante
della RAM può produrre miglioramenti notevoli.
39
13
Il supporto della RAM
•  Per aumentare la banda banda passante della RAM occorre che questa
venga organizzata in banchi in modo da poter leggere o scrivere più
word (anziché una sola) per ciclo di clock.
•  Se una linea è formata da n word, la linea viene distribuita su n banchi
di RAM, ciascuno dei quali memorizza (allo stesso indirizzo di tutti
gli altri banchi) una delle n word della linea.
•  Gli n banchi possono quindi essere letti in parallelo, estraendo così in
una sola lettura tutte le word di cui è composta una linea.
•  Questo schema è denominato a memoria interlacciata (interleaved
memory) e permette di risparmiare sul tempo necessario a prelevare
un’intera linea dalla RAM (un principio abbastanza simile alla
distribuzione degli strip nei sistemi RAID)
40
Il supporto della RAM
•  H-P3, Fig 5.27: la memoria
interlacciata (c) permette di
mantenere un bus di
ampiezza ragionevole e di
migliorare la velocità di
accesso alla RAM nella
gestione dei cache miss.
•  Usando lo stesso esempio di prima, con la soluzione (c) avremmo:
•  1 ciclo di clock per inviare l’indirizzo della linea mancante, 15 cicli di
clock per prelevare le 4 word della linea (i quattro banchi vengono ora
acceduti in parallelo), 4 × 1 cicli di clock per inviare l’intera linea alla
41 (a)
cache, per un totale di 20 cicli di clock, contro i 65 della soluzione
Cache Set-Associative
•  Una caratteristica fondamentale delle cache Direct-Mapped, è che una
determinata linea della RAM viene memorizzata sempre nella stessa
entry della cache.
•  Naturalmente, più linee di RAM fanno riferimento alla stessa entry
della cache, dato che questa è meno capiente della RAM.
•  Ammettendo un posizionamento più flessibile delle linee di RAM
all’interno della cache è possibile ridurre in numero di cache miss,
e quindi aumentare le prestazioni del sistema.
•  Un tale effetto può essere ottenuto mediante le cache set-associative
ad n vie, dove n è di solito pari a 2, 4, o 8.
42
14
Cache Set-Associative
•  Una cache set-associativa ad n vie è suddivisa in più insiemi, ciascuno
dei quali è formato da n entry e può quindi contenere n linee.
•  Ogni linea della RAM corrisponde esattamente ad uno ed un solo
insieme della cache, ma quella linea può essere memorizzata in una
qualsiasi delle n entry dell’insieme.
•  Quindi, in una cache set-associativa l’insieme (notate, non più l’entry,
come nelle cache direct-mapped) che contiene una linea è stabilito da:
(numero della linea in RAM) modulo (numero di insiemi della cache)
43
Cache Set-Associative
•  Una cache direct mapped e una cache set-associativa a 2 vie, entrambe
in grado di memorizzare 8 linee. Nella prima, la linea 12 può andare
solo nella entry numero 4. Nella seconda, la stessa linea può andare
nella entry 0 o nella entry 1, che fanno parte dello “zeresimo” insieme
(H-P3, Fig. 5.4. Vedere anche H-P5, Fig. B.2)
44
Cache Set-Associative
•  Quindi, una volta individuato l’insieme che può contenere una certa
linea, occorre ancora verificare se una delle entry di quell’insieme
contiene la linea indirizzata (il che viene fatto con una ricerca
associativa su tutti gli elementi dell’insieme).
•  Se una linea indirizzata manca va portata in cache, e inserita in una
qualsiasi entry. Naturalmente è meglio scegliere una entry libera.
•  Se invece tutte le entry dell’insieme sono occupate occorre
sovrascrivere una delle linee dell’insieme. Di solito si sacrifica
quella indirizzata meno di recente (quindi, si applica una politica
di rimpiazzamento LRU).
•  L’hardware necessario per implementare un tale tipo di cache è più
sofisticato, ma da prestazioni migliori rispetto ad una cache Direct45
Mapped.
15
Cache Set-Associative
•  Come esempio, consideriamo due cache con quattro entry, la prima
cache è di tipo direct-mapped, la seconda è set-associativa a 2 vie.
•  Supponiamo vengano generati indirizzi per le linee di RAM di
indirizzo 0, 8, 0, 6, 8.
•  Qual è il numero di cache miss prodotti dalle due cache?
46
Cache Set-Associative
•  Nel caso della cache direct-mapped, le varie linee indirizzate verranno
messe nelle seguenti entry della cache:
Indirizzo della linea
Entry nella cache
0
0 modulo 4 = 0
6
6 modulo 4 = 2
8
8 modulo 4 = 0
•  I riferimenti “0, 8, 0, 6, 8” genereranno quindi 5 cache miss, in quanto
le linee 0 e 8 si alternano all’interno della stessa entry della cache, e il
primo riferimento a qualsiasi linea genera ovviamente un cache miss.
47
Cache Set-Associative
•  Nel caso della cache set-associativa a 2 vie, le 4 entry sono suddivise
in 2 insiemi, di indice 0 e 1, e le linee indirizzate verranno sistemate
nei seguenti insiemi:
Indirizzo della linea
Insieme nella cache
0
0 modulo 2 = 0
6
6 modulo 2 = 0
8
8 modulo 2 = 0
•  Usando i riferimenti “0, 8, 0, 6, 8” le linee 0 e 8 vengono messe in due
entry separate dello stesso insieme, per cui il secondo riferimento alla
linea 0 non genera cache miss. Quando viene indirizzata la linea 6
(generando un cache miss) la linea 8 in cache viene rimossa
(algoritmo LRU), e il successivo riferimento alla linea 8 genera cache
miss. In totale si hanno 4 cache miss.
48
16
Cache Set-Associative
•  Se la cache set-associativa fosse a 4 vie, si può verificare facilmente
che verrebbero generati 3 cache miss.
•  Più in generale, una cache associativa in cui c’è un solo unico grande
insieme, e una linea può essere sistemata in una qualsiasi entry della
cache, prende il nome di cache completamente associativa (fully
associative cache).
•  Tali cache fornirebbero le prestazioni migliori in termini di cache
miss, ma per cache con qualche migliaio di entry sono troppo
complesse e costose da realizzare.
•  Tuttavia il concetto rimane valido: quanto maggiore è il numero di
entry in cui possiamo sistemare una linea in cache (ossia, quanto
maggiore è n, il numero di vie della cache), tanto migliori sono le
prestazioni.
49
Cache Set-Associative
•  La frequenza di fallimenti nella cache dati per diversi tipi di cache di
uguale dimensione) usando come benchmark SPEC2000 (PattersonHennessy, fig. 5.16. Vedere anche H-P5 fig. B.4)
Associatività
Frequenza dei fallimenti
1 via (direct mapped)
10.3%
2 vie
8.6%
4 vie
8.3%
8 vie
8.1%
•  I vantaggi tra diversi livelli di associatività sembrano minimi, ma se
consideriamo quanto costa servire anche un solo cache miss…
50
Prestazioni: un semplice esempio
•  Come vengono influenzate le prestazioni di una CPU dalla presenza di
un sistema di caching? Facciamo un esempio, assumendo (sono valori
ragionevoli):
–  tempo di esecuzione di una istruzione (CPI): 1 ciclo di clock
–  average miss rate: 2%
–  numero medio di riferimenti in memoria per istruzione: 1,5
–  Tempo necessario ad accedere un dato in caso di cache miss: 100
cicli di clock (della CPU)
51
17
Prestazioni: un semplice esempio
•  Quanti CPI ci vogliono per eseguire una istruzione, assumendo una
cache perfetta? (cache miss = 0, tempo di accesso = 0).
Risposta = 1 CPI
•  E Se non ci fosse proprio la cache?
–  CPI = 1 + 100 × 1,5 = 151
•  E con la cache?
–  CPI = 1 × 0,98 + 0,02 × 100 × 1,5 = 4 (circa, assumendo una cache
con tempo di accesso pari a 0).
52
Miglioramento delle Prestazioni
• 
La presenza di una cache ha un effetto tanto più positivo sulle
prestazioni di un sistema quanto più:
1. 
si riesce a diminuire il costo (in termini di tempo) necessario per
servire un cache miss.
2. 
si riesce a diminuire la frequenza dei cache miss.
53
Riduzione del costo di un cache miss
•  Il gap di prestazioni tra CPU e RAM tende ad allargarsi nel tempo, e
quindi il costo di un cache miss si fa sempre più grave.
•  Abbiamo già visto una tecnica, la memoria interlacciata, per ridurre il
tempo necessario a recuperare una linea mancante in RAM
•  Un altro modo per ridurre il costo dei cache miss e di non dover
andare fino in RAM per recuperare una linea mancante, mediante
l’uso di più livelli di cache.
•  In questo modo, si riesce tra l’altro a raggiungere un accettabile tradeoff tra l’avere una cache veloce quanto la CPU (ma costosa, e quindi
piccola) e una cache sufficientemente grande da contenere una buona
54
parte della RAM (più lenta, ma più economica)
18
Caching a più livelli
L1-istr.
16/64K
L1-dati
16/64K
L2
Cache
L2
Cache
L3
Cache
•  In un sistema di cache a più livelli, le cache sono normalmente
inclusive, ossia: L1 ⊆ L2 ⊆ L3
•  Nei moderni multi-core, ogni core ha a disposizione L1 ed L2 private,
mentre L3 è condivisa. L1 ed L2 risiedono sullo stesso chip del
processore, mentre L3 può essere: sullo stesso chip; su un chip
separato nello stesso package; sulla motherboard.
55
Caching a più livelli
• 
Nel caso di un sistema con almeno due livelli di cache, è importante
che:
1.  le cache di primo livello abbiamo un tempo di accesso simile alla
velocità della CPU, in modo da non rallentarne l’esecuzione delle
istruzioni in caso di cache hit.
2.  la cache di secondo livello abbia una dimensione
sufficientemente maggiore della cache di primo livello, in modo
da ridurre significativamente il numero di cache miss rispetto alla
cache di primo livello.
3.  Ragionamento analogo vale per la cache di terzo livello rispetto a
quella di secondo livello.
56
Caching a più livelli
• 
Nei processori attualmente in produzione si osservano più o meno le
seguenti caratteristiche:
Cache
tempo di accesso
dimensioni
L1
1÷4 clock cycles
16÷64 Kbytes
L2
8÷15 clock cycles
256÷1024 Kbytes
L3
25÷50 clock cycles
2÷10 Mbytes
57
19
Riduzione del numero di cache miss
• 
È il secondo modo per rendere l’uso di una cache il più efficace
possibile. Qui si può agire in più modi.
• 
Abbiamo già visto che l’uso di cache set-associative diminuisce la
frequenza dei cache miss.
• 
Abbiamo anche visto che una giusta dimensione delle linee rispetto
alla dimensione della cache ottimizza il numero di cache miss per
una data dimensione.
• 
Infine, ovviamente, i cache miss si riducono con l’aumento delle
dimensioni della cache.
58
Riduzione del numero di cache miss
• 
Nel tempo, la dimensione delle cache (specie L2 ed L3) è
costantemente aumentata: ad esempio, nel 2001 una cache di
secondo livello aveva la dimensione della memoria principale di un
desktop del 1991.
• 
Addirittura, se la cache di un certo livello è troppo piccola rispetto
alla quantità di dati/istruzioni di cui ha bisogno un programma, si
verifica un vero e proprio fenomeno di thrashing, simile a quello che
può presentarsi nel funzionamento della memoria virtuale visto nel
corso di Sistemi Operativi.
59
Un caso di studio: il Core i7
• 
Vediamo, nel caso reale del Core i7, in quale misura 3 livelli di
cache permettano di evitare di andare a prelevare i dati mancanti
fino ai banchi di memoria centrale.
• 
La tabella del prossimo lucido (H-P5, Fig. 2.23) riporta, nella
colonna 2, la percentuale di data miss per L1, per diversi
benchmarks. In colonna 3 vediamo invece come migliori il miss rate
usando il prefetch dei dati e le load speculative (entrambe le tecniche
implementate nell’i7)
60
20
Un caso di studio: il Core i7
• 
H-P5, Fig. 2.23: notare come migliori il miss rate usando il prefetch
dei dati e le load speculative (tecniche entrambe implementate
nell’i7)
61
Un caso di studio: il Core i7
Ed ecco il miss rate
dei dati rispetto alle
cache L2 ed L3. I
miss cache di L3
sono un sottoinsieme dei miss
cache di L2 che sono
un sotto-insieme dei
miss cache di L1
(H-P5, Fig. 2.25)
62
Prestazioni degli algoritmi e cache
• 
Normalmente, gli algoritmi sono valutati solo a livello teorico, in
base al numero di operazioni da compiere per risolvere un problema,
rispetto alla “dimensione” del problema.
• 
A livello pratico tuttavia, il modo in cui un computer funziona può
influenzare enormemente le effettive prestazioni di un programma.
• 
Pensate ad esempio a come “interferisce” il sistema operativo
nell’esecuzione di un programma, cioè durante la vita del processo
che esegue il codice di quel programma (context switches, page
faults, system call…)
63
21
Prestazioni degli algoritmi e cache
• 
La presenza della cache è uno degli aspetti pratici, nell’esecuzione
dei programmi, che può influenzarne enormemente i tempi di
esecuzione.
• 
Così, un algoritmo che sembra più efficiente di altri a livello teorico,
può in realtà fornire prestazioni peggiori se fatto girare su un sistema
che usa un sistema di cache.
• 
Un esempio è il Radix Sort, un algoritmo di ordinamento che, per
array molto grandi (milioni di elementi), fornisce prestazioni
migliori del Quick Sort in termini del numero di operazioni richieste
per l’ordinamento. Ma cosa succede se prendiamo in considerazione
la cache?
64
Prestazioni degli algoritmi e cache
• 
Per questa ragione, sono state
inventate nuove versioni di Radix Sort
(e di molti altri algoritmi
comunemente usati) che tengono in
considerazione la presenza della
gerarchia di memorie dei computer, in
modo da limitare le inefficienze
nascoste.
(Patterson-Hennessy, Fig. 5.19)
65
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
La tecnologia per costruire la memoria principale del computer usa
una serie di sigle che indicano diverse tecnologie di costruzione e
funzionamento. Sappiamo già cosa vuol dire DRAM. Ecco
brevemente le altre:
• 
DIMM: Dual Inline Memory Modules. I chip di DRAM sono
normalmente montati su piccole schede contenenti da 4 a 16 DRAM
organizzate in modo da memorizzare i dati in blocchi di 8 bytes
(+ ECC), le DIMM appunto.
66
22
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
SDRAM: Synchronous DRAM. Sono DRAM dotate di un clock, in
modo da potersi sincronizzare col clock del controller della RAM, e
ottimizzare le prestazioni.
• 
DDR: Double Data Rate. Sono DRAM (in realtà, SDRAM) in cui è
possibile trasferire dati sia sul fronte discendente che su quello
ascendente del clock, in questo modo raddoppiando le prestazioni
rispetto a normali DRAM.
67
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
DDR2, DDR3, DDR4… L’acronimo DDR indica ormai
comunemente una sequenza di standard, in cui viene man mano
aumentato il clock della DRAM, e quindi la quantità di dati trasferiti
per secondo
• 
In realtà viene anche diminuito il voltaggio di funzionamento, in
modo da diminuire i consumi. DDR=2,5 volt; DDR2= 1,8 volt;
DDR3=1,5 volts; DDR4=1,2 volts.
68
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
Prestazioni e codici delle DDR DRAM nel 2010 (H-P5, Fig. 2.14)
69
23
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
GDRAM: Graphics (Synchronous) DRAM. Sono particolari tipi
di DDR (e infatti sono anche denominate GDDR) adatte a gestire le
alte larghezze di banda richieste dai processori grafici. In particolare:
– 
Trasferiscono più bit in parallelo delle DRAM
– 
Sono collegate direttamente alla GPU mediante saldature (e non
mediante normali socket come nelle DIMM) in modo da
diminuire la dispersione del segnale e permettere un aumento
della frequenza del clock
70
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
FLASH Memory. Sono particolari tipi di EEPROM (Electronically
Erasable Programmable Read-Only Memory): possono non solo
essere lette, ma anche riscritte. Tuttavia, la riscrittura avviene a
livello di interi blocchi di dati, ossia anche i dati non modificati del
blocco vanno riscritti.
• 
Vengono usate al posto degli hard disk in molti dispositivi portatili,
dove possono svolgere anche la funzione di memoria primaria.
71
DRAM, DIMM, SDRAM, DDR,
DDR2, DDR3, GDRAM, FLASH…
• 
Le principali caratteristiche delle memorie Flash sono:
– 
Sono statiche, quindi mantengono i dati anche se non alimentate
– 
Hanno un numero di cicli di riscrittura limitato a circa 100.000
per blocco.
– 
Sono meno costose delle SDRAM e più degli Hard Disk, con un
costo di circa 1$ per Gbyte memorizzato.
– 
In lettura sono poco più lente delle SDRAM e circa mille volte
più veloci degli Hard Disk. In scrittura tuttavia le prestazioni
peggiorano sensibilmente (fino a 100 volte più lente delle
SDRAM).
72
24