Esaminiamo cosa succede realmente quando viene eseguita un'istruzione come mov eax,[ds:ebx*2+4]
.
Prima la CPU deve calcolare l'indirizzo virtuale. L'indirizzo virtuale sarebbe ebx*2+4
.
Successivamente la CPU aggiunge l'indirizzo di base del registro segmenti all'indirizzo virtuale per ottenere un indirizzo lineare. L'indirizzo di base per ogni registro di segmento è memorizzato nella CPU e per la maggior parte dei registri di segmento (per la maggior parte dei SO) è zero, quindi questo può accadere velocemente. Nota: qui ci sono anche alcuni controlli di protezione, ma ignoralo.
Una volta che la CPU ha un indirizzo lineare, deve essere convertito in un indirizzo fisico (ad esempio, una posizione RAM effettiva). Per fare questo tutto è suddiviso in (4 pagine KiB o possibilmente più grandi) e ci sono diversi livelli di strutture di impaginazione. Ad esempio (modalità lunga), la CPU utilizza PML4 (Page Map Level 4) per trovare il PDPT (Page Pointer Table), quindi utilizzare una voce PDPT per trovare il PD (Page Directory), quindi utilizzare una voce PD per trovare il PT (Page Table). La voce della tabella di pagina contiene l'indirizzo fisico della pagina. Aggiungendo "l'offset nella pagina" dall'indirizzo virtuale all'indirizzo fisico della pagina ottiene l'indirizzo fisico finale. Nota: qui ci sono anche alcuni controlli di protezione coinvolti in ogni fase, ma ignoralo.
Tutte queste ricerche di tabelle richiedono tempo. Per accelerarlo, la CPU memorizza nella cache le traduzioni "indirizzo virtuale per indirizzo fisico" (comprese le autorizzazioni finali / risultanti per i controlli di protezione) nel TLB (Translation Look-aside Buffer).
Una volta che la CPU conosce l'indirizzo fisico, può leggere i dati da quell'indirizzo fisico. Anche questo può essere lento, quindi la CPU utilizza altre cache per memorizzare nella cache i dati effettivi.
Ora; il problema con le cache è che (a causa di "materiale tecnico") più sono grandi e più lenti sono. Per ottenere le migliori prestazioni e cache più grandi, hanno più livelli di cache - ad es. L1 molto piccolo molto veloce, L2 più grande / più lento, ecc. Per le cache vicine alla CPU, può anche aiutare ad avere cache differenti per istruzioni e dati (diversi set di lavoro, diversi pattern di accesso, ecc.). Questo è il motivo per cui c'è L1I e L1D, quindi L2 (unificato) e forse L3 (unificato).
Ovviamente lo stesso vale per i TLB - ci possono essere più livelli di TLB e TLB diversi per istruzioni e dati (più alcune cache in particolare per le strutture di paging di alto livello per ridurre il sovraccarico TLB).
Tornando a quelle traduzioni "indirizzo virtuale a indirizzo fisico" - se la traduzione non è memorizzata nella cache nel TLB, la CPU deve recuperare (potenzialmente) molte tabelle dalla RAM per eseguire la traduzione. Una mancata TLB causa diversi recuperi e questi recuperi potrebbero (o potrebbero non essere) soddisfatti dai dati ancora nella cache L2 o L3.