La maggior parte dei sistemi operativi ha qualche metodo per visualizzare l’utilizzo della CPU. In Windows, questo è Task Manager.
L’utilizzo della CPU è generalmente rappresentato come una semplice percentuale del tempo della CPU speso in attività non inattive. Ma questa è un po’ una semplificazione. In qualsiasi sistema operativo moderno, la CPU passa effettivamente del tempo in due modalità ben distinte:
- Modalità Kernel
In modalità Kernel, il codice in esecuzione ha accesso completo e illimitato all’hardware sottostante. Può eseguire qualsiasi istruzione della CPU e fare riferimento a qualsiasi indirizzo di memoria. La modalità kernel è generalmente riservata alle funzioni di livello più basso e più affidabili del sistema operativo. I crash in modalità kernel sono catastrofici; fermeranno l’intero PC.
- Modalità utente
In modalità utente, il codice in esecuzione non ha la capacità di accedere direttamente all’hardware o alla memoria di riferimento. Il codice in esecuzione in modalità utente deve delegare alle API di sistema per accedere all’hardware o alla memoria. A causa della protezione offerta da questo tipo di isolamento, i crash in modalità utente sono sempre recuperabili. La maggior parte del codice in esecuzione sul tuo computer verrà eseguito in modalità utente.
È possibile abilitare la visualizzazione del tempo del kernel in Task Manager, come ho fatto nello screenshot sopra. La linea verde è il tempo totale della CPU; la linea rossa è il tempo del Kernel. Lo spazio tra i due è il tempo dell’utente.
Queste due modalità non sono semplici etichette; sono imposte dall’hardware della CPU. Se il codice che viene eseguito in modalità utente tenta di fare qualcosa al di fuori della sua sfera di competenza – come, ad esempio, accedere ad un’istruzione privilegiata della CPU o modificare la memoria a cui non ha accesso – viene lanciata un’eccezione trappabile. Invece che l’intero sistema si blocca, solo quella particolare applicazione si blocca. Questo è il valore della modalità utente.
l’hardware della CPU x86 fornisce effettivamente quattro anelli di protezione: 0, 1, 2 e 3. Solo gli anelli 0 (Kernel) e 3 (User) sono tipicamente usati.
Se stiamo usando solo due anelli di isolamento, non è chiaro dove dovrebbero andare i driver dei dispositivi– il codice che ci permette di usare le nostre schede video, tastiere, mouse, stampanti e così via. Questi driver vengono eseguiti in modalità Kernel, per ottenere le massime prestazioni, o in modalità Utente, per ottenere la massima stabilità? In Windows, almeno, la risposta è che dipende. I driver dei dispositivi possono essere eseguiti in modalità utente o kernel. La maggior parte dei driver sono spostati sul lato utente della recinzione in questi giorni, con la notevole eccezione dei driver delle schede video, che hanno bisogno di prestazioni in modalità kernel a mani nude. Ma anche questo sta cambiando; in Windows Vista, i driver video sono segmentati in sezioni User e Kernel. Forse è per questo che i giocatori si lamentano che Vista è circa il 10% più lento nei giochi.
Il confine esatto tra queste modalità è ancora poco chiaro. Quale codice dovrebbe essere eseguito in modalità utente? Quale codice dovrebbe essere eseguito in modalità Kernel? O forse ridefiniremo semplicemente il pavimento come il seminterrato– l’ascesa della virtualizzazione ha portato alla creazione di un nuovo anello sotto tutti gli altri, Ring -1, che ora conosciamo come virtualizzazione hardware x86.
La modalità utente è chiaramente un bene pubblico netto, ma ha un costo. Passare dalla modalità utente a quella kernel è costoso. Davvero costoso. È il motivo per cui il software che lancia eccezioni è lento, per esempio. Le eccezioni implicano transizioni in modalità kernel. Certo, abbiamo così tante prestazioni ora che raramente dobbiamo preoccuparci delle prestazioni di transizione, ma quando si ha bisogno di prestazioni massime, si inizia sicuramente a preoccuparsi di queste cose.
Probabilmente l’esempio più pubblico di ridisegnare la linea utente / kernel è nei webserver. IIS 6 di Microsoft ha spostato una parte considerevole delle sue funzionalità di base in modalità Kernel, in particolare dopo che un particolare webserver open-source ha sfruttato la modalità Kernel per creare un’enorme vittoria nei benchmark di settore. Era una sorta di guerra inutile, se me lo chiedete, dal momento che le ottimizzazioni del kernel (in entrambi i campi) si applicano solo al contenuto HTML statico. Ma questo è il modo di tutte le guerre, benchmark o altro.
La rigida segregazione del codice della CPU tra modalità utente e kernel è completamente trasparente alla maggior parte di noi, ma è letteralmente la differenza tra un computer che si blocca sempre e un computer che si blocca catastroficamente ogni volta. Questo è ciò che a noi programmatori extra-crash-code-writing piace chiamare “progresso”. Quindi, a nome di tutti i programmatori di tutto il mondo, vorrei dire grazie User mode. Sei una roccia!