A legtöbb operációs rendszer rendelkezik valamilyen módszerrel a CPU-kihasználtság megjelenítésére. A Windowsban ez a Feladatkezelő.
A CPU-használat általában a nem üresjárati feladatokra fordított CPU-idő egyszerű százalékos arányaként jelenik meg. Ez azonban egy kicsit leegyszerűsítés. Bármely modern operációs rendszerben a CPU valójában két nagyon különböző üzemmódban tölti az időt:
- Kernel üzemmód
Mag üzemmódban a végrehajtó kód teljes és korlátlan hozzáféréssel rendelkezik a mögöttes hardverhez. Bármilyen CPU utasítást végre tud hajtani, és bármilyen memóriacímre hivatkozhat. A kernel üzemmódot általában az operációs rendszer legalacsonyabb szintű, legmegbízhatóbb funkciói számára tartják fenn. A kernel üzemmódban bekövetkező összeomlások katasztrofálisak; leállítják az egész számítógépet.
- Felhasználói üzemmód
A felhasználói üzemmódban a végrehajtó kód nem képes közvetlenül hozzáférni a hardverhez vagy hivatkozni a memóriára. A felhasználói módban futó kódnak a hardverhez vagy a memóriához való hozzáféréshez a rendszer API-it kell delegálnia. Az ilyenfajta elszigeteltség által nyújtott védelem miatt a felhasználói módban bekövetkező összeomlások mindig helyreállíthatók. A számítógépen futó kódok többsége felhasználói módban fut.
A Feladatkezelőben engedélyezhető a Kernel-idő megjelenítése, ahogy a fenti képernyőképen is tettem. A zöld vonal a teljes CPU-idő; a piros vonal a Kernel-idő. A kettő közötti különbség a felhasználói idő.
Ez a két üzemmód nem egyszerű címkék; a CPU hardvere kényszeríti ki őket. Ha a felhasználói módban futó kód megpróbál valami olyat tenni, ami kívül esik a hatáskörén – például hozzáférni egy kiváltságos CPU-utasításhoz vagy módosítani egy olyan memóriát, amihez nincs hozzáférése -, akkor csapdázható kivételt dob. Ahelyett, hogy az egész rendszer összeomlana, csak az adott alkalmazás omlik össze. Ez a felhasználói mód értéke.
Az x86 CPU hardver valójában négy védelmi gyűrűt biztosít: 0, 1, 2 és 3. Általában csak a 0 (Kernel) és a 3 (User) gyűrűket használjuk.
Ha csak két szigetelési gyűrűt használunk, akkor egy kicsit nem világos, hogy hova kerüljenek az eszközillesztők – az a kód, amely lehetővé teszi számunkra a videokártyák, billentyűzetek, egerek, nyomtatók stb. használatát. Ezek az illesztőprogramok Kernel módban futnak, a maximális teljesítmény érdekében, vagy User módban, a maximális stabilitás érdekében? Legalábbis a Windowsban a válasz az, hogy ez attól függ. Az eszközillesztők felhasználói vagy rendszermag módban is futhatnak. A legtöbb illesztőprogram manapság a felhasználói oldalra kerül, kivéve a videokártya-illesztőprogramokat, amelyeknek csupaszív Kernel-módú teljesítményre van szükségük. De még ez is változik; a Windows Vista rendszerben a videóillesztő-programok felhasználói és kernelmódú részekre vannak felosztva. Talán ezért panaszkodnak a játékosok, hogy a Vista körülbelül 10 százalékkal lassabban teljesít a játékokban.
Az üzemmódok közötti pontos határvonal még mindig kissé homályos. Milyen kódot kell futtatni a felhasználói módban? Milyen kódnak kell futnia Kernel módban? Vagy talán egyszerűen csak átdefiniáljuk a padlót alagsornak– a virtualizáció térhódítása egy új gyűrű létrehozásához vezetett az összes többi alatt, a -1-es gyűrűhöz, amit ma már x86-os hardveres virtualizációként ismerünk.
A felhasználói mód egyértelműen nettó közjó, de ennek ára van. A felhasználói és a rendszermag mód közötti átmenet költséges. Nagyon drága. Ezért lassúak például a kivételeket dobáló szoftverek. A kivételek kernel üzemmódba való átmenetet jelentenek. Igaz, most már annyi teljesítményünk van, hogy ritkán kell törődnünk az átmenet teljesítményével, de amikor végső teljesítményre van szükséged, akkor határozottan elkezdesz törődni ezekkel a dolgokkal.
A felhasználói/kernel határvonal újrarajzolásának talán legnyilvánvalóbb példája a webkiszolgálókban van. A Microsoft IIS 6 az alapfunkcióinak jelentős részét Kernel módba helyezte át, leginkább azután, hogy egy bizonyos nyílt forráskódú webkiszolgáló a Kernel módot kihasználva hatalmas iparági benchmark győzelmet aratott. Ha engem kérdezel, ez egy eléggé értelmetlen háború volt, mivel a kernel optimalizálás (mindkét táborban) csak a statikus HTML tartalomra vonatkozik. De ilyen minden háború, legyen szó benchmarkról vagy másról.
A CPU szigorúan elkülöníti a kódot a felhasználói és a kernel üzemmód között, ami a legtöbbünk számára teljesen átlátszó, de szó szerint ez a különbség egy állandóan összeomló számítógép és egy állandóan katasztrofálisan összeomló számítógép között. Ez az, amit mi, extra-crashy-kódot író programozók “fejlődésnek” szeretünk nevezni. Ezért minden programozó nevében köszönetet mondok a User mode-nak. Te vagy a király!