
Es wäre vernünftig anzunehmen, dass es für den Kernel ziemlich einfach wäre, nichts zu tun - aber das ist es nicht. Auf der
Kernel Recipes 2018- Konferenz sprach
Rafael Vysotsky darüber, was Prozessoren tun, wenn sie nichts zu tun haben, wie der Kernel sie verarbeitet, welche Strategie sie derzeit verfolgen und wie ihre jüngste Arbeit am
Leerlaufzyklus die Energiesituation von Systemen verbessert
hat , die nichts tun. .
Der Inaktivitätszyklus, eines der von Vysotsky unterstützten Kernel-Subsysteme, steuert, was die CPU tut, wenn sie keine Prozesse ausführen muss. Vysotsky hat alle Definitionen sehr genau angegeben: Eine CPU ist eine solche Entität, die Anweisungen aus dem Speicher empfangen und gleichzeitig mit anderen Entitäten im selben System ausführen kann, die sich mit derselben Sache befassen. Auf dem einfachsten Einzelprozessorsystem mit einem Kern ist dieser Kern die CPU. Wenn der Prozessor mehrere Kerne hat, ist jeder dieser Kerne eine CPU. Wenn jeder der Kerne mehrere Schnittstellen zum gleichzeitigen Ausführen von Anweisungen hat - Intel nennt ein solches System "
Hyperthreading " -, ist jeder dieser Threads eine CPU.
Die CPU ist inaktiv, wenn keine Aufgaben auszuführen sind. Genauer gesagt verfügt der Linux-Kernel über mehrere interne Klassen zum Versenden, von denen eine eine spezielle Leerlaufklasse ist. Wenn auf dieser CPU in keiner der Klassen außer der Inaktivitätsklasse Aufgaben vorhanden sind, wird die CPU als inaktiv betrachtet. Wenn das Gerät dies nicht zulässt, muss die CPU unbrauchbare Anweisungen ausführen, bis die eigentliche Arbeit auftaucht. Dies ist jedoch eine äußerst ineffiziente Nutzung von Elektrizität, weshalb die meisten Prozessoren mehrere Niedrigenergiezustände unterstützen, in die der Kern sie überträgt, bis sie für nützliche Arbeit benötigt werden.
Sie können nicht einfach in einen Zustand der Untätigkeit eintreten oder diesen verlassen. Das Ein- und Aussteigen dauert einige Zeit. Wenn Sie in diesen Zustand eintreten, steigt außerdem der Stromverbrauch des aktuellen Zustands geringfügig an. Wenn Sie ihn verlassen, wird der Zustand verbraucht, in den der Prozessor wechselt. Und je tiefer der Inaktivitätszustand ist, desto weniger Energie verbraucht der Prozessor, desto höher sind die Kosten für das Ein- und Aussteigen in solche Zustände. Dies bedeutet, dass bei kurzen Inaktivitätszeiten die beste Nutzung der Computerressourcen eine geringe Untätigkeit ist. Für längere Zeiträume werden die Kosten für den Übergang in einen tieferen Zustand der Untätigkeit durch eine Erhöhung der eingesparten Energiemenge gerechtfertigt. Daher liegt es im Interesse des Kernels, vorherzusagen, wie lange der Prozessor im Leerlauf sein wird, bevor entschieden wird, wie tief der von ihm benötigte Inaktivitätszustand ist. Dies ist die Aufgabe des Untätigkeitszyklus.
In diesem Zyklus stellt der Scheduler fest, dass die CPU inaktiv ist, da ihr keine Aufgaben zugewiesen sind, die ihr zugewiesen werden könnten. Dann ruft der Scheduler den Regler auf, der versucht, die beste Vorhersage des geeigneten Untätigkeitszustands zu geben, den Sie eingeben können. Jetzt gibt es im Kernel zwei Steuerelemente, Menü und Leiter. Sie werden in verschiedenen Fällen verwendet, aber beide versuchen ungefähr dasselbe zu tun: den Status des Systems zu überwachen, wenn die CPU in einen Ruhezustand übergeht, und die Zeit, die sie für Inaktivität aufgewendet hat. Dies geschieht, um vorherzusagen, wie lange die CPU in einem Zustand der Inaktivität sein wird und welcher Zustand daher für diese Situation am besten geeignet ist.
Diese Arbeit wird durch den CPU-Scheduler-Timer besonders kompliziert. Der Scheduler startet diesen Timer, um die Zugriffszeit auf die CPU aufzuteilen: Wenn mehrere Aufgaben auf einem Prozessor ausgeführt werden müssen, kann jede von ihnen nur wenig ausgeführt und dann regelmäßig zugunsten einer anderen Aufgabe verschoben werden. Dieser Timer muss nicht auf einer inaktiven CPU ausgeführt werden, da es keine Aufgaben gibt, zwischen denen die CPU aufgeteilt werden muss. Wenn der Timer auf einer inaktiven CPU ausgeführt werden darf, verhindert dies außerdem, dass der Controller tiefe Leerlaufzustände auswählt, wodurch die Intervalle begrenzt werden, in denen die CPU inaktiv ist. Daher schaltete der Scheduler in Kerneln bis 4.16 den Timer aus, bevor er den Regler aufrief. Als die CPU nach einer Unterbrechung aufwachte, entschied der Scheduler, ob für die Ausführung Aufgaben erforderlich waren, und startete den Timer gegebenenfalls neu.
Wenn der Controller eine lange Zeit der Inaktivität vorhersagt und sich herausstellt, dass diese Zeitspanne wirklich lang ist, „gewinnt“ der Controller: Die CPU befindet sich in einem Zustand tiefer Inaktivität, und Energie wird gespart. Wenn der Regler jedoch einen langen Zeitraum der Inaktivität vorhersagt und sich herausstellt, dass dieser Zeitraum kurz ist, „verliert“ der Regler, da sich die Kosten für die Eingabe einer tiefen Untätigkeit nicht auszahlen, indem für einen kurzen Zeitraum der Inaktivität Energie gespart wird. Schlimmer noch, wenn der Regler eine kurze Ausfallzeit vorhersagt, „verliert“ er unabhängig von der Ausfallzeit: Wenn sich herausstellte, dass der Zeitraum lang war, verpasste er die Gelegenheit, zu sparen, und wenn er kurz war, wurden die Kosten für das Stoppen und Neustarten des Timers verschwendet. Mit anderen Worten, da Ressourcen für das Stoppen und Starten des Timers aufgewendet werden, ist es nicht sinnvoll, ihn zu stoppen, wenn der Controller eine kurze Ausfallzeit vorhersagt.
Vysotsky beschloss, den Betrieb des Reglers zu ändern, kam jedoch zu dem Schluss, dass das Hauptproblem darin besteht, dass der Timer gestoppt wird, bevor der Regler aufgerufen wird, dh bevor der empfohlene Inaktivitätszustand bekannt wird. Er gab einen Leerlaufzyklus in Kernel 4.17 zurück, so dass die Entscheidung zum Stoppen des Timers getroffen wurde, nachdem der Regler seine Empfehlung abgegeben hatte. Wenn er eine lange Ausfallzeit vorhergesagt hat, stoppt der Timer, um die CPU nicht vorzeitig zu aktivieren. Wenn angenommen wird, dass die Ausfallzeit kurz ist, bleibt der Timer übrig, um zu vermeiden, dass beim Herunterfahren Ressourcen verschwendet werden. Dies bedeutet, dass der Timer auch eine Sicherheitsfunktion ausführt, die die CPU aufweckt, wenn sich herausstellt, dass die Ausfallzeit länger als vorhergesagt ist, und dem Regler eine zweite Chance für die richtige Entscheidung gibt.
Wenn eine inaktive CPU durch einen Interrupt aufwacht, sei es ein unaufhaltsamer Timer oder ein anderes Ereignis, entscheidet der Scheduler sofort, ob Arbeit vorhanden ist. Wenn Arbeit vorhanden ist, wird der Timer nach Bedarf neu gestartet. Wenn nicht, wird der Controller aufgerufen. Da dies bedeutet, dass der Regler jetzt sowohl bei laufendem als auch bei nicht funktionierendem Timer aufgerufen werden kann, muss der Regler aufgerufen werden, um dies zu berücksichtigen.
Nachdem Wyssotski die Tabelle der Siege und Verluste studiert hat, glaubt er, dass seine Änderungen das Bild verbessern werden. Wenn eine lange Zeit der Inaktivität vorhergesagt wird, stoppt der Timer immer noch, sodass sich hier nichts ändert. Wir gewinnen, wenn die Ausfallzeit lang ist, und wir verlieren, wenn sie kurz ist. Wenn jedoch eine kurze Ausfallzeit vorhergesagt wird, gewinnen wir: Wenn sich herausstellt, dass die Zeitspanne wirklich kurz ist, sparen wir beim Stoppen und Starten des Timers, und wenn sie lang ist, weckt uns ein nicht gestoppter Timer und gibt uns die Möglichkeit, eine weitere Vorhersage zu treffen.

Da die Spieltheorie nicht als vollständiger Ersatz für die reale Situation dienen kann, hat Vysotsky diesen Ansatz auf vielen Systemen getestet. Die obige Grafik ist typisch für alle getesteten Systeme. Es zeigt die zeitliche Abhängigkeit des Stromverbrauchs von einem Leerlaufsystem. Die grüne Linie ist der alte Untätigkeitszyklus, die rote Linie ist der neue. Nach dem neuen Schema wird weniger Energie verbraucht, außerdem ist es vorhersehbarer. Nicht alle getesteten CPUs hatten eine so große Lücke zwischen den Linien, aber alle zeigten eine flache rote Linie unter ungleichmäßigem Grün. Wie Vysotsky sagte, ist es weniger wahrscheinlich, dass dieses neue Schema kurze Inaktivitätsperioden vorhersagt, aber häufiger stellt sich heraus, dass es in Bezug auf ihre kurze Dauer richtig ist.
Auf eine Frage des Publikums antwortete Wyssotski, dass diese Arbeit von der Architektur abhänge. Insbesondere Intel-Prozessoren werden davon profitieren, da sie über eine relativ große Anzahl von Inaktivitätszuständen verfügen, aus denen der Regulierer den auswählen kann, der ihm die besten Erfolgschancen bietet, wenn die Vorhersage korrekt ist. ARM-Prozessoren werden aber auch von der neuen Schaltung profitieren.
Ein Rückgang des Stromverbrauchs um 20% im Leerlauf scheint eine unbedeutende Leistung zu sein, ist es aber nicht. Jedes System, das mit Spitzenlasten ziemlich gut umgehen möchte, sollte im normalen Modus über eine Gangreserve verfügen, die sich bei Inaktivität manifestiert. Die obige Grafik zeigt die Prozessorauslastung für das Jahr auf meinem Server, die sich mit E-Mail, Dateiübertragung, VPN, NTP usw. befasst. Gelb bedeutet einfache Zeit. Das Einsparen von 20% dieser Energie würde meinem Anbieter gefallen, und für den Planeten wäre es besser.