De flesta operativsystem har någon metod för att visa CPU-användning. I Windows är detta Aktivitetshanteraren.
CPU-användning representeras i allmänhet som en enkel procentsats av CPU-tid som spenderas på uppgifter som inte är vilande. Men detta är en liten förenkling. I alla moderna operativsystem tillbringar CPU:n faktiskt tid i två mycket olika lägen:
- Kärnläge
I kärnläge har den exekverande koden fullständig och obegränsad tillgång till den underliggande hårdvaran. Den kan utföra vilken CPU-instruktion som helst och referera till vilken minnesadress som helst. Kärnläget är i allmänhet reserverat för operativsystemets lägsta nivå och mest betrodda funktioner. Krascher i kärnläge är katastrofala; de stoppar hela datorn.
- Användarläge
I användarläge har den exekverande koden ingen möjlighet att få direkt tillgång till maskinvaran eller referera till minnet. Kod som körs i användarläge måste delegera till systemets API:er för att få tillgång till maskinvara eller minne. På grund av det skydd som denna typ av isolering ger kan krascher i användarläge alltid återställas. Det mesta av den kod som körs på din dator exekveras i användarläge.
Det är möjligt att aktivera visning av kärntid i Aktivitetshanteraren, vilket jag har gjort i skärmdumpen ovan. Den gröna linjen är den totala CPU-tiden, den röda linjen är Kernel-tiden. Skillnaden mellan de två är användartid.
De här två lägena är inte bara etiketter, utan de är påtvingade av CPU-hårdvaran. Om kod som körs i användarläget försöker göra något som ligger utanför dess behörighet – som till exempel att få tillgång till en privilegierad CPU-instruktion eller ändra ett minne som den inte har tillgång till – så utlöses ett undantag som kan fångas upp. Istället för att hela systemet kraschar kraschar endast det specifika programmet. Det är värdet av User mode.
x86 CPU-hårdvara tillhandahåller faktiskt fyra skyddsringar: 0, 1, 2 och 3. Endast ringarna 0 (Kernel) och 3 (User) används vanligtvis.
Om vi bara använder två isoleringsringar är det lite oklart vart enhetsdrivrutinerna ska ta vägen – koden som gör det möjligt för oss att använda våra grafikkort, tangentbord, möss, skrivare och så vidare. Körs dessa drivrutiner i Kernel-läge, för maximal prestanda, eller körs de i User-läge, för maximal stabilitet? I Windows, åtminstone, är svaret att det beror på. Enhetsdrivrutiner kan köras i antingen användar- eller kärnläge. De flesta drivrutiner är numera förlagda till användarsidan av staketet, med det anmärkningsvärda undantaget för drivrutiner för grafikkort, som behöver en mycket hög prestanda i kernel-läge. Men även det håller på att förändras. I Windows Vista är videodrivrutinerna uppdelade i användar- och kärnsektioner. Kanske är det därför som spelare klagar på att Vista presterar cirka 10 procent långsammare i spel.
Den exakta gränsen mellan dessa lägen är fortfarande något oklar. Vilken kod ska köras i användarläget? Vilken kod ska köras i kärnläge? Eller kanske ska vi bara omdefiniera golvet som källaren – virtualiseringens framväxt drev fram skapandet av en ny ring under alla andra, Ring -1, som vi nu känner till som x86-hårdvaruvirtualisering.
Användarläget är helt klart en offentlig nettovinst, men det har en kostnad. Det är dyrt att övergå mellan användar- och kärnläge. Riktigt dyrt. Det är därför programvara som kastar undantag är långsam, till exempel. Undantag innebär övergångar till kärnläge. Visserligen har vi så mycket prestanda nu att vi sällan behöver bry oss om övergångsprestanda, men när man behöver ultimat prestanda börjar man definitivt bry sig om dessa saker.
Det mest offentliga exemplet på omdragning av gränsen mellan användare och kärna är förmodligen i webbservern. Microsofts IIS 6 flyttade en stor del av sin kärnfunktionalitet till kärnläge, framför allt efter att en viss webbserver med öppen källkod utnyttjat kärnläge för att skapa en enorm seger i branschens benchmark. Det var ett ganska meningslöst krig, om du frågar mig, eftersom kärnans optimeringar (i båda lägren) endast gäller statiskt HTML-innehåll. Men så är det med alla krig, benchmark eller inte.
CPU:ns strikta uppdelning av kod mellan användar- och kärnläge är helt genomskinlig för de flesta av oss, men det är bokstavligen skillnaden mellan en dator som kraschar hela tiden och en dator som kraschar katastrofalt hela tiden. Detta är vad vi programmerare som skriver extra krånglig kod vill kalla ”framsteg”. På alla programmerares vägnar vill jag därför tacka User mode. Ni rockar!