Wie wird der Lastdurchschnitt berücksichtigt?

    Frage Aussage


    Kürzlich wurde mir während eines Interviews mit einem großen Unternehmen eine einfache Frage gestellt: Was ist Load Average? Ich weiß nicht, wie oft ich richtig geantwortet habe, aber ich habe persönlich festgestellt, dass ich die genaue Antwort nicht wirklich kenne.

    Die meisten Leute wissen wahrscheinlich, dass der Lastdurchschnitt die durchschnittliche Last des Systems über einen bestimmten Zeitraum (1, 5 und 15 Minuten) ist. Sie können auch einige Details aus diesem Artikel herausfinden ., wie man es benutzt. In den meisten Fällen reicht dieses Wissen aus, um die Systemlast nach dem Wert von LA abzuschätzen, aber ich bin von Beruf Physiker. Wenn ich einen "Durchschnitt über einen bestimmten Zeitraum" sehe, interessiere ich mich sofort für die Abtastrate in diesem Intervall. Und wenn ich den Begriff „Ressourcen warten“ sehe, wird es interessant, wie viel und wie lange Sie warten müssen und wie viele einfache Prozesse Sie starten müssen, um in kurzer Zeit eine hohe LA zu erreichen. Und vor allem, warum geben die Antworten auf diese Fragen keine 5 Minuten Arbeit mit Google? Wenn Sie sich auch für diese Feinheiten interessieren, heißen wir Sie bei cat willkommen.

    Hier stimmt etwas nicht ...


    Zunächst bestimmen wir, was wir wissen. Im Allgemeinen ist der Lastdurchschnitt die durchschnittliche Anzahl anstehender CPU-Ressourcen für eines von drei Zeitintervallen. Wir wissen auch, dass dieser Wert im Normalzustand im Bereich von 0 bis 1 liegt und die Einheit 100% Last eines Einkernsystems ohne Überlastung entspricht. In Zukunft werde ich das System als Single-Core betrachten, da es einfacher und aussagekräftiger ist.

    Was ist hier falsch?

    Erstens wissen wir alle, dass das arithmetische MittelMehrere Mengen sind gleich der Summe dieser Mengen geteilt durch ihre Anzahl. Aus der Information, dass wir genau diese Menge absolut unverständlich haben. Wenn wir während der gesamten Minute anstehende Prozesse zählen, entspricht der Durchschnittswert der Anzahl der Prozesse pro Minute geteilt durch eins. Wenn wir jede Sekunde zählen, nimmt die Anzahl der Prozesse in jeder Berechnung mit dem Bereich ab und wir teilen durch 60. Je höher die Abtastfrequenz während der Datenerfassung ist, desto niedriger ist der Durchschnittswert.

    ZweitensWas bedeutet ein "auf Ressourcen wartender Prozess"? Wenn wir eine große Anzahl schneller Prozesse auf einmal starten, werden alle in der Warteschlange stehen und logischerweise sollte LA für kurze Zeit auf völlig inakzeptable Werte anwachsen, und die kontinuierliche Überwachung sollte konstante Sprünge zeigen, was im Normalfall nicht der Fall ist.

    Drittens sollte bei einem Single-Core-System mit 100% Last der Lastdurchschnitt gleich 1 sein. Es besteht jedoch keine Abhängigkeit von den Parametern dieses Kernels, obwohl die Anzahl der Prozesse erheblich variieren kann. Diese Frage kann entweder durch die korrekte Definition der "anstehenden Prozessressourcen" oder durch das Vorhandensein einer Art Normalisierung der Kernelparameter gelöst werden.

    Literatur


    Antworten auf diese Fragen zu finden war nicht so schwierig. Die Wahrheit ist nur auf Englisch und nicht alles wurde sofort klar. Es wurden speziell zwei Artikel gefunden:
    "Untersuchen des Lastdurchschnitts"
    "UNIX-Lastdurchschnitts" Der
    Benutzer Rondo schlug auch den zweiten Teil des Artikels mit einer genaueren Untersuchung des mathematischen Geräts vor: "UNIX-Lastdurchschnitts". Teil 2 “
    Und auch ein kleiner Test für diejenigen, die bereits alles verstehen, wie im zweiten Artikel angegeben.

    Für Interessierte empfehle ich Ihnen, beide Artikel zu lesen, obwohl sie sehr nahe beieinander liegen. Im ersten Teil werden viele verschiedene interessante Details des Systembetriebs allgemein beschrieben und im zweiten Teil wird die LA-Berechnung detaillierter analysiert, wobei Beispiele mit Belastungen und Sachverständigenkommentaren gegeben werden.

    Ein bisschen Atommagie


    Anhand dieser Materialien können Sie feststellen, dass jedem aufgerufenen Prozess eine begrenzte Zeitspanne für die Nutzung der CPU eingeräumt wird. In der Standard-Intel-Architektur beträgt diese Zeitspanne 10 ms. Dies ist eine ganze Hundertstelsekunde und in den meisten Fällen benötigt der Vorgang nicht so viel Zeit. Wenn jedoch ein Prozess die ganze ihm zugewiesene Zeit verwendet wurde, wird ein Hardware-Interrupt aufgerufen und das System erhält die Kontrolle über den Prozessor zurück. Zusätzlich wird alle 10ms der Tick Counter erhöht (Jiffies Counter). Diese Ticks werden ab dem Moment des Systemstarts gezählt und alle 500 Ticks (alle 5 Sekunden) wird der Lastdurchschnitt berechnet.

    Der Berechnungscode selbst befindet sich im Kernel in der timer.c-Datei (der Code ist für Version 2.4, in Version 2.6 ist alles etwas verstreut, aber die Logik hat sich nicht geändert. Ich hoffe, es gibt auch keine wesentlichen Änderungen, aber ehrlich gesagt habe ich die neuesten Versionen nicht überprüft.) :

    646 unsigned long avenrun[3];
    647 
    648 static inline void calc_load(unsigned long ticks)
    649 {
    650         unsigned long active_tasks; /* fixed-point */
    651         static int count = LOAD_FREQ;
    652 
    653         count -= ticks;
    654         if (count < 0) {
    655                 count += LOAD_FREQ;
    656                 active_tasks = count_active_tasks();
    657                 CALC_LOAD(avenrun[0], EXP_1, active_tasks);
    658                 CALC_LOAD(avenrun[1], EXP_5, active_tasks);
    659                 CALC_LOAD(avenrun[2], EXP_15, active_tasks);
    660         }
    661 }
    

    Wie Sie sehen, werden die gleichen drei LA-Werte nacheinander berechnet, es wird jedoch nicht angegeben, was genau und wie genau dies berücksichtigt wird. Dies ist auch kein Problem, der Code der Funktion count_active_tasks () befindet sich in derselben Datei, etwas höher:

    625 static unsigned long count_active_tasks(void)
    626 {
    627         struct task_struct *p;
    628         unsigned long nr = 0;
    629 
    630         read_lock(&tasklist_lock);
    631         for_each_task(p) {
    632                 if ((p->state == TASK_RUNNING ||
    633                      (p->state & TASK_UNINTERRUPTIBLE)))
    634                         nr += FIXED_1;
    635         }
    636         read_unlock(&tasklist_lock);
    637         return nr;
    638 }
    

    Und CALC_LOAD liegt in sched.h zusammen mit einigen interessanten Konstanten:

     61 #define FSHIFT          11              /* nr of bits of precision */
     62 #define FIXED_1         (1<>= FSHIFT;
    

    Aus all dem kann man schließen, dass der Kernel alle 5 Sekunden prüft, wie viele Prozesse sich im Zustand RUNNING und UNINTERRUPTIBLE befinden (bei anderen UNIX-Systemen ist dies übrigens nicht der Fall) und für jeden dieser Prozesse den Zähler um FIXED_1 inkrementiert, was 1 <entspricht
     49 /*
     50  * These are the constant used to fake the fixed-point load-average
     51  * counting. Some notes:
     52  *  - 11 bit fractions expand to 22 bits by the multiplies: this gives
     53  *    a load-average precision of 10 bits integer + 11 bits fractional
     54  *  - if you want to count load-averages more often, you need more
     55  *    precision, or rounding will get you. With 2-second counting freq,
     56  *    the EXP_n values would be 1981, 2034 and 2043 if still using only
     57  *    11 bit fractions.
     58  */
    

    Ein bisschen nuklearer Verfall


    Nein, der Kern des Systems zerfällt hier nicht, sondern nur die CALC_LOAD-Formel, nach der der Lastmittelwert auf dem Gesetz des radioaktiven Zerfalls oder einfach des exponentiellen Zerfalls basiert . Dieses Gesetz ist nichts anderes als eine Lösung für die Differentialgleichung, dh jeder neue Wert wird aus dem vorherigen berechnet, und die Abnahmerate der Anzahl der Elemente hängt direkt von der Anzahl der Elemente ab.
    Die Lösung dieser Differentialgleichung ist das Exponentialgesetz:



    Tatsächlich ist der Lastdurchschnitt nicht der Durchschnittswert im üblichen Sinne des arithmetischen Mittels. Dies ist eine diskrete Funktion, die regelmäßig ab dem Start des Systems berechnet wird. Darüber hinaus ist der Wert der Funktion die Anzahl der Prozesse, die im System unter exponentiellen Dämpfungsbedingungen ausgeführt werden.
    Wir beobachten eine solche Konstruktion, indem wir den berechneten Teil von CALC_LOAD in mathematischer Sprache umschreiben:



    2 ^ 11 ist in diesem Fall für uns gleichbedeutend mit Einheit, wir haben es anfangs festgelegt und überall hinzugefügt, die Anzahl neuer Prozesse wird auch in diesen Mengen berechnet. A , wobei T das Messintervall ist (1, 5 oder 15 Minuten).

    Es ist anzumerken, dass für ein festes Zeitintervall und eine feste Zeit zwischen Messungen die Werte des Exponenten im Voraus berechnet und als Konstante verwendet werden können, was im Code erfolgt. Die letzte Operation - Verschiebung nach rechts um 11 Bits ergibt den gewünschten Wert für den Lastmittelwert, wobei die niedrigeren Ordnungen verworfen werden.

    Schlussfolgerungen


    Wenn Sie nun verstehen, wie LA berechnet wird, können Sie versuchen, die am Anfang des Artikels gestellten Fragen zu beantworten:
    1) Der Durchschnittswert ist nicht der arithmetische Durchschnitt, sondern der Durchschnittswert der Funktion, der alle 5 Sekunden ab dem Start des Systems berechnet wird.
    2) "Ausstehende CPU-Ressourcen" sind alle Prozesse, die sich im Status RUNNING und UNINTERRUPTIBLE befinden. Und wir beobachten keine signifikanten Sprünge im Lastmittelwert während der kontinuierlichen Überwachung, da der abklingende Exponent die Rolle einer Glättungsfunktion spielt (obwohl Sie sie bemerken, wenn Sie einen Zeitraum von 1 Minute berücksichtigen).
    3) Und hier ist eine der interessantesten Schlussfolgerungen. Tatsache ist, dass die obige Lastmittelwertfunktion bei allen Werten von n monoton auf diesen Wert ansteigt, wenn n
    hier ist



    Neben der Beantwortung der ursprünglich verfügbaren Fragen wirft das Parsen des Codes jedoch neue Fragen auf. Ist beispielsweise ein Fading-Exponent anwendbar, um die Anzahl anstehender Prozesse zu reduzieren? Wenn wir den radioaktiven Zerfall in Betracht ziehen, ist seine Geschwindigkeit nur durch die Anzahl der Kerne begrenzt, in unserem Fall wird bei einer großen Anzahl von Prozessen alles an der CPU-Bandbreite anliegen. Wenn wir die erhaltene Formel mit dem Exponentialgesetz vergleichen, wird auch klar, dass T die Dauer des Datensatzintervalls (1, 5 oder 15 Minuten) ist. Kernel-Entwickler sind daher der Meinung, dass die Rate der Abnahme des Lastdurchschnitts umgekehrt proportional zur Dauer der Messungen ist, was zumindest für mich etwas unauffällig ist. Nun, es ist nicht schwierig, Situationen zu simulieren, in denen große LA-Werte die Systemlast nicht wirklich anzeigen oder umgekehrt.

    Letztendlich hat man den Eindruck, dass eine Glättungsfunktion gewählt wurde, um den Lastmittelwert zu berechnen, der seinen Wert so schnell wie möglich verringert, was im Allgemeinen logisch ist, um eine endliche Zahl zu erhalten, aber den tatsächlichen Prozess nicht anzeigt. Und wenn mir jemand genau erklärt, warum der Aussteller und warum in dieser Form, bin ich sehr dankbar.

    Jetzt auch beliebt: