Come può la cache essere così veloce?


37

Ecco uno screenshot di un benchmark della cache:

Risultati del benchmark AIDA64 Cache & Memory

Nel benchmark la velocità di lettura della cache L1 è di circa 186 GB / s, con latenza di circa 3-4 cicli di clock. Come si raggiunge una tale velocità?

Considerare qui la memoria: la velocità massima teorica è 665 MHz (frequenza di memoria) x 2 (doppia velocità dati) x 64 bit (larghezza bus) che è di circa 10,6 GB / s, che è più vicino al valore di riferimento di 9,6 GB / s .

Ma con la cache L1, anche se potessimo leggere ad ogni ciclo con il processore alla sua frequenza massima (3 GHz), avremmo bisogno di circa 496 linee di dati per raggiungere un tale throughput che sembra irrealistico. Questo vale anche per altre cache.

Cosa mi sto perdendo? Come calcoliamo il throughput di una cache dai suoi parametri?


14
hai considerato quanto piccola è la cache L1,2,3 e ugualmente dove risiede fisicamente. Suggerimento, non è necessario preoccuparsi di uno standard bus se si possiede l'intero chip
JonRB,

2
Inoltre: il benchmark conosce abbastanza bene cosa sta facendo per garantire che alcuni dati con cui viene testato non vengano mantenuti direttamente all'interno di un registro?
Rackandboneman,

7
@rackandboneman: AIDA64 è un punto di riferimento rispettato, non qualcosa che qualcuno ha appena hackerato in C e ha permesso al compilatore di ottimizzare alcuni carichi! Suppongo che le parti del microbenchmark siano scritte in assembly, con le versioni SSE o AVX.
Peter Cordes,

1
@Peter Cordes risposta soddisfacente - a una domanda necessaria.
rackandboneman,

1
Giusto per mettere i thinkg in una prospettiva fisica: in 1,4 nanosecondi la luce viaggia circa un piede e mezzo. Ciò significa che se la cache si trovasse sull'altro lato della scheda madre, una latenza del genere potrebbe interrompere la relatività. O sii un errore di misura .
Arthur,

Risposte:


35

Questa CPU ha ...

2 core Un'istruzione da 32 KB e cache di primo livello di dati da 32 KB (L1) per ciascun core

Poiché ci sono due core, possiamo aspettarci che il benchmark esegua due thread in parallelo. Il loro sito Web fornisce informazioni notevolmente ridotte, tuttavia, se guardiamo qui , le CPU con più core sembrano fornire throughput L1 corrispondentemente più elevati. Quindi penso che ciò che viene visualizzato sia il throughput totale con tutti i core che lavorano in parallelo. Quindi, per la tua CPU, dovremmo dividere per due per un core e una cache:

Read   93 GB/s
Write  47 GB/s
Copy   90 GB/s

Ora, il fatto che "copia" sia 2 volte più veloce di "scrivi" è altamente sospetto. Come potrebbe copiare più velocemente di quanto possa scrivere? Scommetto che ciò che il benchmark visualizza come "copia" è la somma del throughput read + write, e in questo caso sarebbe sia in lettura che in scrittura a 45 GB / s, ma visualizzerebbe 90, perché è un benchmark e chi diavolo si fida dei benchmark? Quindi ignoriamo "copia".

Read   93 GB/s => 30 bytes/clock
Write  47 GB/s => 15 bytes/clock

Ora, un registro a 128 bit è di 16 byte, abbastanza vicino, quindi sembra che questa cache possa fare due letture a 128 bit e una scrittura per clock.

Questo è esattamente ciò che vorresti davvero semplificare quelle istruzioni di scricchiolio del numero SSE: due letture e una scrittura per ciclo.

Molto probabilmente questo sarebbe implementato con molte linee di dati parallele, che è il solito modo per trasportare molti dati molto velocemente all'interno di un chip.


4
A pagina 55 del documento @ next-hack collegamenti ad esso riporta "Internamente, gli accessi hanno un massimo di 16 byte. [...] Due operazioni di caricamento e un'operazione di memorizzazione possono essere gestite ogni ciclo". Questo spiega perché leggere è due volte più veloce: può fare due letture nella stessa operazione mentre fa anche una scrittura.
Tom Carpenter,

2
Sì, conta chiaramente la copia BW = leggi e scrivi. Sembra altrettanto valido come l'alternativa, poiché è significativo che le letture e le scritture possano essere eseguite in parallelo. Si noti che i numeri dei PO per L2 / L3 hanno una copia non molto superiore a quella di scrittura e inferiore per la memoria. Il bus di memoria DDR3 non è full duplex: le stesse righe di dati sono necessarie per leggere e scrivere. (Per ulteriori informazioni sulla larghezza di banda memcpy / memset x86 con negozi NT rispetto ai negozi normali, vedere stackoverflow.com/questions/43343231/… ).
Peter Cordes,

6
Stai indovinando che IvyBridge può fare 2 letture e 1 scrittura nello stesso ciclo di clock. Ti capita di avere ragione, ma solo in circostanze molto limitate. IvB ha solo 2 porte AGU, quindi normalmente è limitato a 2 operazioni di memoria per clock, fino a una delle quali può essere un archivio . Ma 256 b carichi / archivi AVX richiedono 2 cicli per essere eseguiti nelle porte di carico / deposito, mentre nel primo ciclo è necessaria solo la AGU. Quindi un uop di indirizzo negozio può essere eseguito sulla porta 2/3 durante quel 2 ° ciclo di un carico 256b senza costare alcuna larghezza di banda del carico. (Store-data uops eseguito sulla porta 4.) Fonte: agner.org/optimize microarch pdf
Peter Cordes,

2
Una famiglia AMD Bulldozer o CPU Ryzen ti darebbe la stessa lettura = 2x numeri di scrittura, ma in realtà sono limitati a 2 operazioni di memoria per clock (fino a uno può essere una scrittura) senza scappatoie. lettura / scrittura / copia non rileva la differenza, ma Triad can ( a[i] = b[i] + c[i]). A proposito, Intel Haswell e successivi hanno un negozio-AGU sulla porta 7 in grado di gestire modalità di indirizzamento semplici (non indicizzate), in modo che possano eseguire 2 carichi + 1 store uops per clock. (E il percorso dei dati verso L1D è 256b, quindi raddoppia la larghezza di banda L1D.) Vedi la descrizione di David Kanter: realworldtech.com/haswell-cpu/5
Peter Cordes,

1
@AliChen: L'OP ha menzionato esplicitamente la latenza di utilizzo del carico a 4 cicli di IvyBridge subito dopo la larghezza di banda, prima di chiedere come può essere così veloce.
Peter Cordes,

27

La risposta di @ peufeu sottolinea che si tratta di larghezze di banda aggregate a livello di sistema. L1 e L2 sono cache private per core nella famiglia Intel Sandybridge, quindi i numeri sono il doppio di quello che può fare un singolo core. Ma questo ci lascia ancora con una larghezza di banda straordinariamente alta e una bassa latenza.

La cache L1D è integrata direttamente nel core della CPU ed è strettamente collegata alle unità di esecuzione del carico (e al buffer di archiviazione) . Allo stesso modo, la cache L1I si trova proprio accanto all'istruzione fetch / decode parte del core. (In realtà non ho esaminato una planimetria di silicio Sandybridge, quindi questo potrebbe non essere letteralmente vero. Il problema / rinominare parte del front-end è probabilmente più vicino alla cache uop decodificata "L0", che consente di risparmiare energia e ha una migliore larghezza di banda rispetto ai decodificatori.)

Ma con cache L1, anche se potessimo leggere ad ogni ciclo ...

Perché fermarsi qui? Intel da Sandybridge e AMD da K8 possono eseguire 2 carichi per ciclo. Le cache multiporta e i TLB sono una cosa.

La scrittura della microarchitettura Sandybridge di David Kanter ha un bel diagramma (che si applica anche alla tua CPU IvyBridge):

(Lo "scheduler unificato" contiene ALU e memory uops in attesa che i loro input siano pronti e / o in attesa della loro porta di esecuzione. (Es vmovdqa ymm0, [rdi]. Decodifica in un uop di carico che deve attendere rdise un precedente add rdi,32non è stato ancora eseguito, per esempio) Intel pianifica gli Uops verso le porte al momento dell'emissione / ridenominazione . Questo diagramma mostra solo le porte di esecuzione per gli Uops di memoria, ma anche gli UU ALU non eseguiti competono per questo. Rimangono nel ROB fino al pensionamento, ma nello scheduler solo fino all'invio a una porta di esecuzione (questa è la terminologia Intel; altre persone usano il problema e inviano in modo diverso)). AMD utilizza programmatori separati per numeri interi / FP, ma le modalità di indirizzamento utilizzano sempre registri interi

Diagramma di memoria SnB di David Kanter

Come mostrato, ci sono solo 2 porte AGU (unità di generazione di indirizzi, che prendono una modalità di indirizzamento simile [rdi + rdx*4 + 1024]e producono un indirizzo lineare). Può eseguire 2 operazioni di memoria per clock (di 128b / 16 byte ciascuna), di cui una è un archivio.

Ma ha un asso nella manica: SnB / IvB esegue 256 b caricamenti / depositi AVX come un singolo uop che richiede 2 cicli in una porta di carico / deposito, ma necessita solo dell'AGU nel primo ciclo. Ciò consente a un uop di indirizzo di negozio di funzionare sull'AGU sulla porta 2/3 durante quel secondo ciclo senza perdere la velocità di carico. Quindi con AVX (che le CPU Intel Pentium / Celeron non supportano: /), SnB / IvB può (in teoria) sostenere 2 carichi e 1 negozio per ciclo.

La tua CPU IvyBridge è la fustella di Sandybridge (con alcuni miglioramenti microarchitetturali, come l' eliminazione di mov , ERMSB (memcpy / memset) e il prefetching hardware della pagina successiva). La generazione successiva (Haswell) ha raddoppiato la larghezza di banda L1D per clock allargando i percorsi dei dati dalle unità di esecuzione a L1 da 128b a 256b, in modo che i carichi AVX 256b possano sostenere 2 per clock. Ha inoltre aggiunto una porta AGU store aggiuntivo per semplici modalità di indirizzamento.

Il throughput di picco di Haswell / Skylake è di 96 byte caricati + memorizzati per clock, ma il manuale di ottimizzazione di Intel suggerisce che il throughput medio sostenuto di Skylake (supponendo ancora che non manchi L1D o TLB) sia ~ 81 B per ciclo. (Un ciclo intero scalare può sostenere 2 carichi + 1 archivio per clock secondo il mio test su SKL, eseguendo 7 uops (dominio non utilizzato) per clock da 4 uops di dominio fuso. Ma rallenta leggermente con operandi a 64 bit anziché 32 bit, quindi a quanto pare c'è un limite di risorse microarchitetturali e non è solo un problema di pianificazione degli indirizzi di negozio alla porta 2/3 e di rubare cicli dai carichi.)

Come calcoliamo il throughput di una cache dai suoi parametri?

Non è possibile, a meno che i parametri non includano numeri di throughput pratici. Come notato sopra, anche L1D di Skylake non riesce a tenere il passo con le sue unità di esecuzione di caricamento / archiviazione per vettori 256b. Anche se è vicino, e può farlo per numeri interi a 32 bit. (Non avrebbe senso avere più unità di carico rispetto alla cache delle porte di lettura, o viceversa. Avresti semplicemente escluso l'hardware che non avrebbe mai potuto essere completamente utilizzato. Nota che L1D potrebbe avere porte extra a cui inviare / ricevere linee / da altri core, nonché per letture / scritture dall'interno del core.)

Il semplice controllo delle larghezze e degli orologi del bus dati non ti dà tutta la storia. La larghezza di banda L2 e L3 (e memoria) può essere limitata dal numero di mancati errori che L1 o L2 possono tracciare . La larghezza di banda non può superare la latenza * max_concurrency e i chip con latenza più elevata L3 (come un Xeon a molti core) hanno una larghezza di banda L3 single-core molto inferiore rispetto a una CPU dual / quad core della stessa microarchitettura. Vedi la sezione "Piattaforme associate alla latenza" di questa risposta SO . Le CPU della famiglia Sandybridge dispongono di 10 buffer di riempimento di riga per tracciare gli errori L1D (utilizzati anche dai negozi NT).

(La larghezza di banda aggregata L3 / memoria con molti core attivi è enorme su un grande Xeon, ma il codice a thread singolo vede una larghezza di banda peggiore rispetto a un quad core alla stessa velocità di clock perché più core significa più stop sul ring bus, e quindi più alto latenza L3.)


Latenza della cache

Come si raggiunge una tale velocità?

La latenza di caricamento del ciclo a 4 cicli della cache L1D è piuttosto sorprendente , soprattutto considerando che deve iniziare con una modalità di indirizzamento come [rsi + 32], quindi deve fare un'aggiunta prima ancora che abbia un indirizzo virtuale . Quindi deve tradurlo in fisico per controllare i tag della cache per una corrispondenza.

(Modalità di indirizzamento diverse da [base + 0-2047]un ciclo aggiuntivo sulla famiglia Intel Sandybridge, quindi negli AGU è presente un collegamento per modalità di indirizzamento semplici (tipiche dei casi di inseguimento del puntatore in cui la latenza a basso carico è probabilmente la più importante, ma anche comune in generale) (Vedi il manuale di ottimizzazione di Intel , sezione 2.3.5.2 L1 DCache di Sandybridge). Ciò presuppone anche che non venga eseguito l'override del segmento e un indirizzo base del segmento 0, il che è normale.)

Deve inoltre esaminare il buffer del negozio per verificare se si sovrappone a tutti i negozi precedenti. E deve capirlo anche se un indirizzo negozio precedente (nell'ordine del programma) uop non è stato ancora eseguito, quindi l'indirizzo negozio non è noto. Ma presumibilmente questo può accadere in parallelo con il controllo di un colpo L1D. Se risulta che i dati L1D non erano necessari perché il forwarding del negozio può fornire i dati dal buffer del negozio, allora non c'è perdita.

Intel utilizza cache VIPT (praticamente indicizzate fisicamente) come quasi tutti gli altri, usando il trucco standard di avere la cache abbastanza piccola e con un'associatività abbastanza elevata da comportarsi come una cache PIPT (senza aliasing) con la velocità di VIPT (può indicizzare in parallelamente alla ricerca virtuale-> fisica TLB).

Le cache L1 di Intel sono 32 kB, associative a 8 vie. La dimensione della pagina è di 4 kB. Ciò significa che i bit di "indice" (che selezionano quale set di 8 modi possono memorizzare nella cache di una determinata riga) sono tutti al di sotto dell'offset della pagina; cioè quei bit di indirizzo sono l'offset in una pagina e sono sempre gli stessi nell'indirizzo virtuale e fisico.

Per maggiori dettagli su questo e altri dettagli sul perché le cache piccole / veloci sono utili / possibili (e funzionano bene se accoppiate con cache più grandi più lente), vedi la mia risposta sul perché L1D è più piccolo / più veloce di L2 .

Le cache di piccole dimensioni possono eseguire operazioni che potrebbero risultare troppo costose in cache di dimensioni maggiori, ad esempio recuperare gli array di dati da un set contemporaneamente ai tag di recupero. Quindi, una volta che un comparatore trova quale tag corrisponde, deve solo combinare una delle otto righe della cache a 64 byte che sono già state recuperate da SRAM.

(Non è poi così semplice: Sandybridge / Ivybridge utilizzano una cache L1D in banca, con otto banchi di blocchi da 16 byte. È possibile ottenere conflitti cache-bank se due accessi alla stessa banca in linee di cache diverse tentano di essere eseguiti nello stesso ciclo. (Ci sono 8 banchi, quindi questo può accadere con indirizzi multipli di 128 a parte, cioè 2 linee di cache.)

Inoltre, IvyBridge non ha penalità per l'accesso non allineato, purché non oltrepassi un limite di 64 KB nella riga della cache. Immagino che capisca quale banca (e) prendere (i) in base ai bit di indirizzo basso e imposta qualsiasi spostamento necessario per ottenere i dati corretti da 1 a 16 byte.

Nelle suddivisioni della cache-line, è ancora solo un singolo uop, ma fa più accessi alla cache. La penalità è ancora piccola, tranne per le divisioni in 4k. Skylake rende anche le suddivisioni in 4k abbastanza economiche, con latenza di circa 11 cicli, lo stesso di una normale divisione della cache-line con una modalità di indirizzamento complessa. Ma la velocità di trasmissione 4k è significativamente peggiore della divisione non suddivisa.


Fonti :


1
È molto chiaro, esauriente e ben scritto! +1!
prossimo hack

8

Nelle moderne CPU, la memoria cache si trova proprio accanto alla CPU sullo stesso die (chip) , è realizzata usando SRAM che è molto, molto più veloce della DRAM che viene utilizzata per i moduli RAM in un PC.

Per unità di memoria (un bit o byte) SRAM è molto più costosa di DRAM. Ecco perché la DRAM viene utilizzata anche in un PC.

Ma poiché SRAM è realizzato con la stessa tecnologia della CPU stessa, è veloce come la CPU. Inoltre, ci sono solo bus interni (su CPU) da gestire, quindi se deve essere un bus largo 496 linee, probabilmente lo è.


Grazie per il tuo interesse. Ho visto in alcuni libri che afferma che le velocità di accesso al registro sono superiori a 300 GB / s, nel qual caso per un processore da 3 GHz il throughput del registro è di 100 B / ciclo, il che non è possibile poiché i registri sono generalmente di 64/128 bit di larghezza, non potevano produrre così tanto. Questo è ciò che mi riguarda. GB / sa è il modo giusto per esprimere la velocità effettiva.
Knight,

3
@Knight tieni presente che IvB (come qualsiasi processore ad alte prestazioni) esegue diverse istruzioni per ciclo, come 3 operazioni ALU, 2 carichi e 1 negozio. La maggior parte di questi può richiedere 2 input (anche carichi, per l'indirizzamento indicizzato) e il carico ne richiede anche 3. Sono 13 registri a 8 byte ciascuno, 104 byte (potrebbe essere stato il caso che una tale combinazione epica non sia consentita, ma lì non indica che sia il caso di IvB, anche se non può essere sostenuto). Se si considerano anche i registri vettoriali, quel numero aumenta ulteriormente.
Harold,

@harold: related: Haswell e Skylake sembrano avere limiti nelle letture dei registri per clock, anche se questo potrebbe essere nel front-end e non influire su un'esplosione di esecuzione dopo che alcuni input sono pronti. Forse è un altro limite microarchitetturale, ma ho trovato colli di bottiglia nel codice che dovrebbero essere in grado di sostenere più operazioni per clock. agner.org/optimize/blog/read.php?i=415#852 . Su Haswell, il mio scenario migliore ha letto ~ 6,5 registri interi per ciclo di clock (sostenuto). Sono anche riuscito a ottenere 7 Uops per clock dispatche / eseguire su Skylake (i negozi sono indirizzo-negozio + dati-negozio).
Peter Cordes,

@PeterCordes che deve essere il front-end anche se giusto? IIRC che era anche il problema storicamente (da PPro a Core2) e non sono sicuro di come i numeri frazionari abbiano un senso altrimenti. Anche se i miei numeri erano un po 'fuori posto
Harold il

@harold: sì, sono abbastanza sicuro che si tratti di un collo di bottiglia del front-end di qualche tipo, probabilmente rinominato. Il collo di bottiglia nella lettura del registro di P6 riguardava registri "freddi" che dovevano essere letti dal file di registro permanente nel ROB in questione. I registri modificati di recente erano ancora presenti nel ROB e non vi erano strozzature. Non ho studiato molto con registri cold vs. hot su HSW / SKL, poiché per qualche ragione non ho pensato di rendere il mio loop più grande di 4 uops / idealmente 1c per iterazione. oops. IDK quanta differenza c'è tra l'inoltro e le letture PRF (che devono avvenire al momento dell'esecuzione, non emettere / rinominare).
Peter Cordes,

4

Le cache L1 sono strutture di memoria abbastanza ampie. L'architettura delle cache L1 nei processori Intel è disponibile in questo manuale (fornito da next-hack). Tuttavia, l'interpretazione di alcuni parametri non è corretta, la "dimensione della linea della cache" non è la "larghezza dei dati", è la dimensione del blocco seriale di accesso ai dati atomici.

La Tabella 2-17 (sezione 2.3.5.1) indica che sui carichi (letture), la larghezza di banda della cache è 2x16 = 32 byte per core per CYCLE . Questo da solo fornisce una larghezza di banda teorica di 96 Gb / s su un core 3GHz. Non è chiaro cosa riporta il benchmark citato, sembra che misuri due core che lavorano in parallelo, quindi produce 192 Gbps per due core.


2

I ritardi di gate sono cosa? 10 picosecondi? I tempi di ciclo per intere operazioni in pipeline sono 333 picosecondi, con varie attività di decodifica e bus e acquisizione di dati con flip-flop prima dell'inizio del successivo ciclo di clock.

Mi aspetto che l'attività più lenta nella lettura di una cache sia in attesa che i dataline si spostino abbastanza lontano (probabilmente questi sono differenziali: un riferimento e una carica effettiva dal bit di lettura) che un comparatore / latch può essere sincronizzato per implementare un positivo- azione di feedback per convertire una piccola tensione in una grande oscillazione di livello logico rail-to-rail (circa 1 volt).


1
Tieni presente che la latenza L1D a 4 cicli include la generazione di indirizzi (per modalità di indirizzamento semplici di [reg + 0-2047]), una ricerca TLB e un confronto di tag (associativa a 8 vie) e l'inserimento dei risultanti fino a 16 byte non allineati sul porta di uscita dell'unità di carico, per l'inoltro ad altre unità di esecuzione. È la latenza 4c per un ciclo che insegue il puntatore come mov rax, [rax].
Peter Cordes,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.