Was macht ein inaktiver CPU-Prozess?

Was macht ein inaktiver CPU-Prozess?

Blick auf die Quelle vonstraceIch habe die Verwendung des Klon-Flags gefunden CLONE_IDLETASK, das dort wie folgt beschrieben wird:

#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */

Bei genauerer Betrachtung habe ich festgestellt, dass dieses Flag, obwohl es darin nicht behandelt wird, man clonetatsächlich vom Kernel während des Bootvorgangs verwendet wird, um inaktive Prozesse (die alle die PID 0 haben sollten) für jede CPU auf der Maschine zu erstellen. Auf einer Maschine mit 8 CPUs werden also mindestens 7 (siehe Frage unten) solcher Prozesse „laufen“ (beachten Sie die Anführungszeichen).

Das führt mich nun zu ein paar Fragen darüber, was dieser „Leerlauf“-Prozess eigentlich macht. Ich gehe davon aus, dass er den NOP-Vorgang kontinuierlich ausführt, bis sein Zeitrahmen endet und der Kernel einen echten Prozess zum Ausführen zuweist oder den Leerlaufprozess erneut zuweist (wenn die CPU nicht verwendet wird). Das ist jedoch nur eine reine Vermutung. Also:

  1. Werden auf einer Maschine mit beispielsweise 8 CPUs 7 solcher Leerlaufprozesse erstellt? (Und wird eine CPU vom Kernel selbst belegt, während keine Arbeit im Benutzerbereich ausgeführt wird?)

  2. Ist der Leerlaufprozess wirklich nur ein unendlicher Strom von NOP-Operationen? (Oder eine Schleife, die dasselbe tut).

  3. Wird die CPU-Auslastung (sagen wir uptime) einfach danach berechnet, wie lange der inaktive Prozess auf der CPU war und wie lange er während eines bestimmten Zeitraums nicht da war?


PS: Ein Großteil dieser Frage ist wahrscheinlich darauf zurückzuführen, dass ich nicht ganz verstehe, wie eine CPU funktioniert. Ich verstehe zwar die Assembly, die Zeitrahmen und die Interrupts, weiß aber nicht, wie eine CPU beispielsweise je nach ausgeführter Funktion mehr oder weniger Energie verbrauchen kann. Ich wäre dankbar, wenn mich auch darüber jemand aufklären könnte.

Antwort1

Die Leerlaufaufgabe wird zur Prozessabrechnung und auch zur Reduzierung des Energieverbrauchs verwendet. Unter Linux wird für jeden Prozessor eine Leerlaufaufgabe erstellt und an diesen Prozessor gebunden. Wenn auf dieser CPU kein anderer Prozess ausgeführt werden kann, wird die Leerlaufaufgabe eingeplant. Die in den Leerlaufaufgaben verbrachte Zeit wird in Tools wie als „Leerlaufzeit“ angezeigt top. (Die Betriebszeit wird anders berechnet.)

Unix scheint immer eine Art Leerlaufschleife gehabt zu haben (aber nicht unbedingt eine tatsächliche Leerlaufaufgabe, sieheGilles' Antwort) und sogar in V1Es wurde eine WAITAnweisung verwendetdie den Prozessor stoppte, bis ein Interrupt auftrat (es stand für „wait for interrupt“). Einige andere Betriebssysteme verwendeten Busy Loops, DOS,OS/2, und insbesondere frühe Versionen von Windows. CPUs verwenden diese Art von „Wait“-Anweisungen schon seit geraumer Zeit, um ihren Energieverbrauch und ihre Wärmeproduktion zu reduzieren. Sie können verschiedene Implementierungen von Leerlaufaufgaben beispielsweise inarch/x86/kernel/process.cim Linux-Kernel: Der Basiskernel ruft einfachHLT, das den Prozessor anhält, bis ein Interrupt auftritt (und den C1-Energiesparmodus aktiviert), behandeln die anderen Implementierungen verschiedene Fehler oder Ineffizienzen (z.BVerwendung MWAITanstelle HLTvon einigen CPUs).

Dies alles ist völlig unabhängig von Leerlaufzuständen in Prozessen, wenn diese auf ein Ereignis (E/A usw.) warten.

Antwort2

Wenn im Lehrbuchdesign eines Prozessplaners kein Prozess geplant werden muss (d. h. wenn alle Prozesse blockiert sind und auf Eingaben warten), wartet der Planer auf eine Prozessorunterbrechung. Die Unterbrechung kann eine Eingabe von einem Peripheriegerät anzeigen (Benutzeraktion, Netzwerkpaket, abgeschlossenes Lesen von einer Festplatte usw.) oder eine Timerunterbrechung sein, die einen Timer in einem Prozess auslöst.

Der Scheduler von Linux hat keinen speziellen Code für den Fall, dass nichts zu tun ist. Stattdessen kodiert er den Fall, dass nichts zu tun ist, als speziellen Prozess, den Leerlaufprozess. Der Leerlaufprozess wird nur dann eingeplant, wenn kein anderer Prozess eingeplant werden kann (er hat effektiv eine unendlich niedrige Priorität). Der Leerlaufprozess ist tatsächlich Teil des Kernels: Er ist ein Kernel-Thread, d. h. ein Thread, der Code im Kernel ausführt, und nicht Code in einem Prozess. (Genauer gesagt gibt es einen solchen Thread für jede CPU.) Wenn der Leerlaufprozess läuft, führt er die Warte-auf-Unterbrechung-Operation aus.

Wie das Warten auf eine Unterbrechung funktioniert, hängt von den Fähigkeiten des Prozessors ab. Beim einfachsten Prozessordesign ist das nur eine Busy-Schleife —

nothing:
    goto nothing

Der Prozessor führt einen Verzweigungsbefehl unaufhörlich aus, der aber nichts bewirkt. Die meisten modernen Betriebssysteme tun dies nicht, es sei denn, sie laufen auf einem Prozessor, auf dem es nichts Besseres gibt, und die meisten Prozessoren haben etwas Besseres. Anstatt Energie zu verschwenden, indem man nichts anderes tut, als den Raum zu heizen, sollte der Prozessor idealerweise ausgeschaltet sein. Der Kernel führt also Code aus, der den Prozessor anweist, sich selbst auszuschalten oder zumindest den größten Teil des Prozessors auszuschalten. Es muss mindestens ein kleines Teil geben, das eingeschaltet bleibt, der Interrupt-Controller. Wenn ein Peripheriegerät einen Interrupt auslöst, sendet der Interrupt-Controller ein Wecksignal an den Hauptprozessor (Teil davon).

In der Praxis verfügen moderne CPUs wie Intel/AMD und ARM über zahlreiche komplexe Energieverwaltungseinstellungen. Das Betriebssystem kann abschätzen, wie lange der Prozessor im Leerlaufmodus bleibt, und wählt abhängig davon verschiedene Energiesparmodi aus. Die Modi bieten unterschiedliche Kompromisse zwischen dem Stromverbrauch im Leerlauf und der Zeit, die zum Ein- und Ausschalten des Leerlaufmodus benötigt wird. Bei einigen Prozessoren kann das Betriebssystem auch die Taktrate des Prozessors senken, wenn es feststellt, dass Prozesse nicht viel CPU-Zeit verbrauchen.

Antwort3

Nein, ein inaktiver Task verschwendet keine CPU-Zyklen. Der Scheduler wählt einfach keinen inaktiven Prozess zur Ausführung aus. Ein inaktiver Prozess wartet auf das Eintreten eines Ereignisses, damit er fortfahren kann. Beispielsweise kann er auf eine Eingabe in einem read()Systemaufruf warten.

Übrigens ist der Kernel kein separater Prozess. Kernelcode wird immer im Kontext eines Prozesses ausgeführt (außer im Sonderfall eines Kernel-Threads). Daher ist es nicht korrekt zu sagen: „Eine CPU wird vom Kernel selbst belegt, während keine Arbeit im Benutzerbereich ausgeführt wird.“

verwandte Informationen