Ogni singola CPU presente in qualsiasi computer, da un notebook economico a un server da un milione di euro, avrà qualcosa chiamato cache. Molto probabilmente ne avrà anche diversi livelli.

Deve essere importante, altrimenti perché dovrebbe essere lì? Ma cosa fa la cache e perché la necessità di averla in diversi livelli?

Leggi anche: Storia di AMD: l’ascesa, la caduta e il risveglio

Cos’è la cache esattamente?

Si tratta di una piccola memoria ma molto veloce che si trova proprio accanto alle unità logiche della CPU. Ma ovviamente c’è molto di più da imparare sulla cache …

Cominciamo col definirla come un sistema di archiviazione quasi magico: è infatti infinitamente veloce, può gestire un numero infinito di transazioni di dati contemporaneamente e mantiene quest’ultimi sempre al sicuro.

Le CPU hanno solo unità logiche, la cache funge da sistema per gestire i trasferimenti di dati. Questo perché il nostro sistema di archiviazione può inviare e ricevere istantaneamente tutti i dati elaborati, cosicché nessuna delle unità logiche verrebbe trattenuta in attesa di una transazione di dati. Ma, come tutti sappiamo, non esiste alcuna tecnologia di archiviazione magica. Invece, abbiamo dischi rigidi o a stato solido, con anche i migliori di questi che non sono nemmeno in grado di gestire da remoto tutti i trasferimenti di dati richiesti per una tipica CPU.

Il motivo è che le CPU moderne sono incredibilmente veloci: richiedono solo un ciclo di clock per aggiungere due valori interi a 64 bit e per una CPU che funziona a 4 GHz, questo sarebbe solo 0,00000000025 secondi o un quarto di nanosecondo. Nel frattempo, la rotazione dei dischi rigidi richiede migliaia di nanosecondi solo per trovare i dati, figuriamoci trasferirli e le unità a stato solido richiedono ancora decine o centinaia di nanosecondi. Tali unità ovviamente non possono essere incorporate nei processori, quindi ciò significa che ci sarà una separazione fisica tra i due. Questo aggiunge più tempo allo spostamento dei dati, peggiorando la situazione.

Quindi ciò di cui abbiamo bisogno è un altro sistema di archiviazione dei dati, che si trova tra il processore e la memoria principale. Deve essere più veloce di un’unità, essere in grado di gestire molti trasferimenti di dati contemporaneamente ed essere molto più vicino al processore. Bene, abbiamo già una cosa del genere e si chiama RAM, ogni sistema ne utilizza svariati GB proprio per questo scopo. Questo tipo di archiviazione è DRAM (memoria dinamica ad accesso casuale) ed è in grado di trasferire i dati molto più velocemente di qualsiasi unità.

Tuttavia, sebbene la DRAM sia super veloce, non è in grado di archiviare tutti i dati. Alcuni dei più grandi chip di memoria DDR4 realizzati da Micron, uno dei pochi produttori di DRAM, contengono 32 Gbit o 4 GB di dati; i dischi rigidi più grandi ne contengono 4.000 volte di più.

Quindi, sebbene abbiamo migliorato la velocità della nostra rete dati, saranno necessari sistemi aggiuntivi – hardware e software – per capire quali dati devono essere conservati nella quantità limitata di DRAM, pronti per la CPU. La DRAM può essere prodotta per essere incorporata nel chip (nota come DRAM incorporata). Le CPU sono piuttosto piccole, quindi non possiamo inserirne tanta.

DRAM cpu

La stragrande maggioranza della DRAM si trova proprio accanto al processore, collegata alla scheda madre, ed è sempre il componente più vicino alla CPU in un sistema informatico. Eppure, non è ancora abbastanza veloce … La DRAM impiega ancora circa 100 nanosecondi per trovare i dati, ma almeno può trasferire miliardi di bit ogni secondo. Sembra che avremo bisogno di un altro stadio della memoria, per passare tra le unità del processore e la DRAM.

SRAM (static random access memory). Laddove la DRAM utilizza condensatori microscopici per memorizzare i dati sotto forma di carica elettrica, SRAM utilizza i transistor per fare la stessa cosa e questi possono funzionare quasi alla stessa velocità delle unità logiche in un processore (circa 10 volte più veloci della DRAM).

C’è, ovviamente, uno svantaggio nella SRAM e, ancora una volta, si tratta di spazio. La memoria basata su transistor occupa molto più spazio della DRAM: per lo stesso chip DDR4 da 4 GB, otterreste meno di 100 MB di SRAM. Ma poiché è realizzato attraverso lo stesso processo produttivo di una CPU, la SRAM può essere costruita direttamente all’interno del processore, il più vicino possibile alle unità logiche. Con ogni fase aggiuntiva, abbiamo aumentato la velocità di spostamento dei dati, al costo di quanto possiamo archiviare. Potremmo continuare ad aggiungere più sezioni, ognuna più veloce ma più piccola.

E così arriviamo a una definizione più tecnica di cosa sia la cache: si tratta di più blocchi di SRAM, tutti situati all’interno del processore; vengono utilizzati per garantire che le unità logiche siano tenute il più occupate possibile, inviando e archiviando i dati a velocità elevatissime.

Leggi anche: Cos’è il Wi-Fi 6? Spieghiamo la prossima generazione di Wi-Fi

Cache: un parcheggio a più livelli

Come abbiamo discusso, la cache è necessaria perché non esiste un sistema di archiviazione magico in grado di tenere il passo con le richieste di dati delle unità logiche in un processore. Le moderne CPU e processori grafici contengono un numero di blocchi SRAM che sono organizzati secondo una gerarchia, una sequenza di cache ordinate come segue:

sequenza di cache

Nell’immagine sopra, la CPU è rappresentata dal rettangolo tratteggiato nero. Le ALU (unità logiche aritmetiche) sono all’estrema sinistra; queste sono le strutture che alimentano il processore, gestendo la matematica che fa il chip. Sebbene tecnicamente non sia cache, il livello di memoria più vicino alle ALU sono i registri (raggruppati in un file di registro).

Ognuno di questi contiene un singolo numero, come un intero a 64 bit; il valore stesso potrebbe essere un pezzo di dati su qualcosa, un codice per un’istruzione specifica o l’indirizzo di memoria di altri dati.

Il file di registro in una CPU desktop è piuttosto piccolo: ad esempio, nel Core i9-9900K di Intel ci sono due banchi di file di registro in ciascun core e quello per i numeri interi contiene solo 180 registri a 64 bit. L’altro file di registro, per i vettori (piccoli array di numeri), ha 168 voci a 256 bit. Quindi il file di registro totale per ogni core è di poco inferiore a 7 kB. In confronto, il file di registro negli Streaming Multiprocessors (l’equivalente della GPU del core di una CPU) di una Nvidia GeForce RTX 2080 Ti ha una dimensione di 256 kB.

I registri sono SRAM, proprio come la cache, ma sono veloci quanto le ALU che servono a spingere i dati dentro e fuori un singolo ciclo di clock. Ma non sono progettati per contenere molti dati (solo un singolo pezzo di esso), motivo per cui ci sono sempre dei blocchi di memoria più grandi nelle vicinanze: questa è la cache di livello 1.

cpu cache di livello 1
CPU Intel Skylake, ingrandita di un singolo core.

L’immagine sopra è una ripresa ingrandita di un singolo core dal design del processore desktop Skylake di Intel. Le ALU e i file di registro possono essere visti all’estrema sinistra, evidenziati in verde. Nella parte superiore centrale dell’immagine, in bianco, c’è la cache dei dati di livello 1. Non contiene molte informazioni, solo 32 kB, ma come i registri, è molto vicina alle unità logiche e funziona alla loro stessa velocità.

L’altro rettangolo bianco indica la cache delle istruzioni di livello 1, anch’essa di 32 kB. Come suggerisce il nome, questa memorizza vari comandi pronti per essere suddivisi in piccole e micro operazioni (solitamente etichettate come μops), affinché le ALU possano eseguirle. Troviamo anche una cache per loro, e potreste classificarla come Livello 0, poiché è più piccola (contiene solo 1.500 operazioni) e vicina delle cache L1.

Ci si potrebbe chiedere perché questi blocchi di SRAM sono così piccoli; perché non hanno una dimensione di un megabyte? Insieme, i dati e le cache delle istruzioni occupano quasi la stessa quantità di spazio nel chip delle unità logiche principali, quindi ingrandirle aumenterebbe la dimensione complessiva del processore.

Ma il motivo principale per cui contengono solo pochi kB è che il tempo necessario per trovare e recuperare i dati aumenta con l’aumentare della capacità di memoria. La cache L1 deve essere molto veloce, quindi è necessario raggiungere un compromesso tra dimensioni e velocità: nella migliore delle ipotesi, sono necessari circa 5 cicli di clock (più lunghi per i valori in virgola mobile) per estrarre i dati da questa cache, pronti per l’uso.

cpu la cache di livello 2
Cache L2 di Skylake: 256 kB di SRAM

Ma se questa fosse l’unica cache all’interno di un processore, le sue prestazioni imploderebbero improvvisamente. Questo è il motivo per cui tutte le CPU dispongono di un altro livello di memoria integrato nei core: la cache di livello 2. Questo è un blocco generale di archiviazione, che contiene istruzioni e dati. È sempre un po’ più grande del livello 1: i processori AMD Zen 2 raggiungono fino a 512 kB di cache L2. Tuttavia, questa dimensione extra ha un costo e impiega circa il doppio del tempo per trovare e trasferire i dati rispetto al Livello 1.

Tornando indietro nel tempo, ai giorni del primo Intel Pentium, la cache di livello 2 era un chip separato, su un piccolo circuito plug-in (come un DIMM RAM) o integrato nella scheda madre principale. Alla fine si è fatto strada sul pacchetto CPU, fino a quando è stato finalmente integrato nel die CPU, in processori come Pentium III e AMD K6-III.

Questo sviluppo è stato presto seguito da un altro livello di cache, ed è avvenuto a causa dell’ascesa dei chip multi-core.

cpu la cache di livello 3 multicore
Chip Intel Kaby Lake. 

Questa immagine, di un chip Intel Kaby Lake, mostra 4 core nella parte centrale sinistra (la GPU integrata occupa quasi la metà del die, a destra). Ogni core ha il proprio set “privato” di cache di livello 1 e 2 (punti bianchi e gialli), ma vengono forniti anche con un terzo set di blocchi SRAM.

La cache di livello 3, anche se si trova direttamente attorno a un singolo core, è completamente condivisa con gli altri: ognuno può accedere liberamente ai contenuti della cache L3 di un altro. È molto più grande (tra 2 e 32 MB) ma anche molto più lenta, con una media di oltre 30 cicli, soprattutto se un core deve utilizzare i dati che si trovano in un blocco di cache a una certa distanza.

Di seguito, possiamo vedere un singolo core nell’architettura Zen 2 di AMD: i dati di livello 1 da 32 kB sono la cache di istruzioni in bianco, il livello 2 da 512 KB in giallo e un enorme blocco di cache L3 da 4 MB in rosso.

singolo core nell'architettura Zen 2 di AMD
CPU AMD Zen 2, ingrandita di un singolo core

Più di un semplice numero

La cache migliora le prestazioni accelerando il trasferimento dei dati alle unità logiche e mantenendo una copia delle istruzioni e dei dati utilizzati di frequente nelle vicinanze. Le informazioni memorizzate nella cache sono suddivise in due parti: i dati stessi e la posizione in cui si trovavano originariamente nella memoria / archiviazione di sistema: questo indirizzo è chiamato tag cache.

Quando la CPU esegue un’operazione e vuole leggere o scrivere dati dalla/alla memoria, inizia controllando i tag nella cache di livello 1. Se è presente quello richiesto (un riscontro nella cache), è possibile accedere a tali dati quasi immediatamente. Se l’informazione non è presente nella cache livello 1, viene creato un nuovo tag cercando attraverso gli altri livelli di cache (fino all’unità di archiviazione principale, se necessario). Ma per fare spazio nella cache L1, qualcos’altro deve essere sempre spostato in L2.

Ciò si traduce in un rimescolamento quasi costante dei dati, il tutto ottenuto in una manciata di cicli di clock. L’unico modo per ottenere ciò, è disporre di una struttura complessa attorno alla SRAM, per gestire la mole di dati. In altre parole: se un core della CPU fosse costituito da una sola ALU, la cache L1 sarebbe molto più semplice, ma poiché ce ne sono dozzine (molte delle quali si destreggiano tra due thread di istruzioni), la cache richiede più connessioni per mantenere tutto in movimento.

cpu-Z cache

È possibile utilizzare programmi gratuiti, come CPU-Z, per controllare le informazioni sulla cache del proprio processore. Ma cosa significano tutte queste informazioni? Un elemento importante è l’associativo del set di etichette: si tratta delle regole che impongono il modo in cui i blocchi di dati dalla memoria di sistema vengono copiati nella cache.

Come vedete nell’immagine CPU-Z di un Intel Core i7-9700K, le sue cache di livello 1 sono suddivise ciascuna in 64 piccoli blocchi, chiamati set, e ognuno di questi è ulteriormente suddiviso in linee di cache (64 byte di dimensione). Set associative significa che un blocco di dati dalla memoria di sistema viene mappato sulle linee della cache in un particolare set, piuttosto che essere libero di mappare ovunque.

La parte a 8 vie ci dice che un blocco può essere associato a 8 linee di cache in un set. Maggiore è il livello di associatività (cioè più “modi”), maggiori sono le possibilità di ottenere una risposta dalla cache quando la CPU va a caccia di dati, ottenendo una riduzione delle penalità causate dai mancati riscontri nella cache. Gli svantaggi sono che aggiunge più complessità, maggiore consumo energetico e può anche ridurre le prestazioni perché ci sono più linee di cache da elaborare per un blocco di dati.

Cache L1 + L2 inclusa, cache L3, criteri di riscrittura
Cache L1 + L2 inclusa, cache L3, criteri di riscrittura

Un altro aspetto della complessità della cache riguarda il modo in cui i dati vengono conservati nei vari livelli. Le regole sono stabilite in qualcosa chiamato politica di inclusione. Ad esempio, i processori Intel Core hanno una cache L1 + L3 completamente inclusa. Ciò significa che gli stessi dati nel Livello 1, possono essere presenti anche nel Livello 3. Potrebbe sembrare che stiano sprecando prezioso spazio nella cache, ma il vantaggio è che se il processore non trova un dato, quando cerca un tag in un livello inferiore, non ha bisogno di cercare attraverso il livello più alto per trovarlo.

Negli stessi processori, la cache L2 non è inclusiva: tutti i dati memorizzati non vengono copiati in nessun altro livello. Ciò consente di risparmiare spazio, ma il sistema di memoria del chip deve cercare in L3 (molto più grande) per trovare un tag mancante.

Esistono altri criteri per la cache, ad esempio quando i dati vengono scritti nella cache e nella memoria di sistema principale. Queste sono chiamate policy di scrittura e la maggior parte delle CPU odierne utilizza cache write-back; questo significa che quando i dati vengono scritti in un livello di cache, c’è un ritardo prima che la memoria di sistema venga aggiornata con una copia di essi. Per la maggior parte dei casi questa pausa viene eseguita finché i dati rimangono nella cache: solo una volta avviata, la RAM ottiene le informazioni.

Per gli ingegneri di CPU scegliere la quantità, il tipo e la politica della cache significa bilanciare il desiderio di avere una maggiore capacità del processore con la maggiore complessità e lo spazio necessario per il die. Se fosse possibile avere 20 MB nella cache di livello 1 completamente associative a 1000 vie senza che i chip diventassero delle dimensioni di una città (e consumassero lo stesso tipo di energia), allora avremmo tutti computer dotati di tali chip.