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 rdi
se un precedente add rdi,32
non è 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
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 :