Die meisten Betriebssysteme verfügen über eine Methode zur Anzeige der CPU-Auslastung. In Windows ist dies der Task-Manager.
Die CPU-Auslastung wird im Allgemeinen als einfacher Prozentsatz der CPU-Zeit dargestellt, die für nicht ruhende Aufgaben verwendet wird. Dies ist jedoch eine starke Vereinfachung. In jedem modernen Betriebssystem verbringt die CPU tatsächlich Zeit in zwei sehr unterschiedlichen Modi:
- Kernel-Modus
Im Kernel-Modus hat der ausführende Code vollständigen und uneingeschränkten Zugriff auf die zugrunde liegende Hardware. Er kann jede CPU-Anweisung ausführen und auf jede Speicheradresse verweisen. Der Kernel-Modus ist im Allgemeinen für die niedrigsten und vertrauenswürdigsten Funktionen des Betriebssystems reserviert. Abstürze im Kernel-Modus sind katastrophal; sie können den gesamten PC zum Stillstand bringen.
- Benutzermodus
Im Benutzermodus hat der ausführende Code keine Möglichkeit, direkt auf die Hardware zuzugreifen oder Speicher zu referenzieren. Code, der im Benutzermodus ausgeführt wird, muss an System-APIs delegieren, um auf Hardware oder Speicher zuzugreifen. Aufgrund des Schutzes, den diese Art der Isolierung bietet, sind Abstürze im Benutzermodus immer wiederherstellbar. Der meiste Code, der auf Ihrem Computer läuft, wird im Benutzermodus ausgeführt.
Es ist möglich, die Anzeige der Kernelzeit im Task-Manager zu aktivieren, wie ich es im obigen Screenshot getan habe. Die grüne Linie ist die gesamte CPU-Zeit, die rote Linie ist die Kernel-Zeit. Die Lücke zwischen den beiden ist die Benutzerzeit.
Diese beiden Modi sind keine bloßen Bezeichnungen; sie werden von der CPU-Hardware erzwungen. Wenn Code, der im Benutzermodus ausgeführt wird, versucht, etwas zu tun, was nicht in seinen Zuständigkeitsbereich fällt – wie z.B. auf eine privilegierte CPU-Anweisung zuzugreifen oder Speicher zu verändern, auf den er keinen Zugriff hat – wird eine abfangbare Ausnahme ausgelöst. Anstatt dass Ihr gesamtes System abstürzt, stürzt nur diese spezielle Anwendung ab. Das ist der Wert des Benutzermodus.
Die Hardware der x86-CPU bietet vier Schutzringe: 0, 1, 2 und 3. Normalerweise werden nur die Ringe 0 (Kernel) und 3 (Benutzer) verwendet.
Wenn wir nur zwei Isolationsringe verwenden, ist es etwas unklar, wo die Gerätetreiber hingehören – der Code, der es uns ermöglicht, unsere Grafikkarten, Tastaturen, Mäuse, Drucker und so weiter zu benutzen. Laufen diese Treiber im Kernel-Modus, um maximale Leistung zu erzielen, oder laufen sie im Benutzermodus, um maximale Stabilität zu gewährleisten? Zumindest unter Windows ist die Antwort: Es kommt darauf an. Gerätetreiber können entweder im Benutzer- oder im Kernelmodus ausgeführt werden. Die meisten Treiber werden heutzutage im Benutzermodus ausgeführt, mit der bemerkenswerten Ausnahme von Grafikkartentreibern, die die volle Leistung des Kernelmodus benötigen. Aber auch das ändert sich; in Windows Vista sind die Grafiktreiber in Benutzer- und Kernelbereiche unterteilt. Vielleicht ist das der Grund, warum sich Gamer beschweren, dass Vista in Spielen etwa 10 Prozent langsamer ist.
Die genaue Grenze zwischen diesen Modi ist immer noch etwas unklar. Welcher Code sollte im Benutzermodus laufen? Welcher Code sollte im Kernel-Modus laufen? Oder vielleicht definieren wir den Boden einfach als Keller – der Aufstieg der Virtualisierung führte zur Schaffung eines neuen Rings unter allen anderen, Ring -1, den wir jetzt als x86-Hardwarevirtualisierung kennen.
Der Benutzermodus ist eindeutig ein öffentliches Gut, aber er hat seinen Preis. Der Übergang zwischen Benutzer- und Kernelmodus ist teuer. Sehr teuer. Deshalb ist zum Beispiel Software, die Ausnahmen auslöst, langsam. Ausnahmen implizieren Kernel-Modus-Übergänge. Zugegeben, wir haben jetzt so viel Leistung, dass wir uns nur selten um die Übergangsleistung kümmern müssen, aber wenn man die ultimative Leistung braucht, fängt man definitiv an, sich über diese Dinge Gedanken zu machen.
Das wahrscheinlich bekannteste Beispiel für die Neuziehung der Benutzer/Kernel-Grenze sind Webserver. Microsofts IIS 6 hat einen beträchtlichen Teil seiner Kernfunktionalität in den Kernel-Modus verlagert, vor allem nachdem ein bestimmter Open-Source-Webserver den Kernel-Modus genutzt hat, um einen großen Benchmark-Sieg zu erringen. Wenn Sie mich fragen, war es ein ziemlich sinnloser Krieg, da die Kernel-Optimierungen (in beiden Lagern) nur für statische HTML-Inhalte gelten. Aber so ist das mit allen Kriegen, ob Benchmark oder nicht.
Die strikte Trennung des Codes zwischen Benutzer- und Kernelmodus ist für die meisten von uns völlig transparent, aber sie ist buchstäblich der Unterschied zwischen einem Computer, der ständig abstürzt, und einem Computer, der immer wieder katastrophal abstürzt. Das ist es, was wir Programmierer, die besonders aufgeregt Code schreiben, gerne als „Fortschritt“ bezeichnen. Also möchte ich im Namen aller Programmierer überall Danke sagen, User mode. Du rockst!