Wie berechnet sich die CPU-Auslastung?

74

Auf meinem Desktop befindet sich ein kleines Widget, das mir meine aktuelle CPU-Auslastung anzeigt. Es zeigt auch die Verwendung für jeden meiner beiden Kerne.

Ich habe mich immer gefragt, wie die CPU berechnet, wie viel Rechenleistung verbraucht wird. Wenn die CPU bei intensiven Berechnungen aufgehängt ist, wie kann sie (oder was auch immer diese Aktivität handhabt) die Nutzung untersuchen, ohne auch aufgehängt zu werden?

Chris Laplante
quelle
1
Fragen Sie nach der CPU-Energieverwaltung, z. B. wenn die CPU erkennt, ob sie viel Strom verbraucht und viel Wärme erzeugt oder nicht? Skylake verfügt beispielsweise über einen Mikrocontroller auf dem Chip für die Energieverwaltung (getrennt von den CPU-Kernen) mit Eingaben von Temperatur- / Leistungssensoren und einigen Informationen zur Arbeitslast. (zB wird es sogar heruntertakten, wenn Code mit vielen Cache- / TLB-Fehlern ausgeführt wird, selbst wenn in Bezug auf das Betriebssystem 100% CPU verwendet wird) ...
Peter Cordes
2
... Dies beantwortet Teil 2 und hat nichts mit Teil 1 zu tun (Lastdurchschnitt auf Betriebssystemebene). Siehe Warum beginnt diese Verzögerungsschleife nach mehreren Iterationen ohne Schlaf schneller zu laufen? für Links. Sie wurden gefragt , wie die CPU kann untersucht seine eigene Nutzung, anstatt die OS - Tracking - CPU - Auslastung. Vielleicht haben Sie das nicht gemeint, aber das ist die Antwort auf diese Interpretation der Frage: P
Peter Cordes

Antworten:

31

Die CPU führt die Nutzungsberechnungen nicht selbst durch. Es verfügt möglicherweise über Hardwarefunktionen, die diese Aufgabe erleichtern, ist jedoch hauptsächlich Aufgabe des Betriebssystems. Daher variieren die Details der Implementierungen offensichtlich (insbesondere bei Multicore-Systemen).

Die allgemeine Idee ist zu sehen, wie lange die Warteschlange der Dinge ist, die die CPU tun muss. Das Betriebssystem kann den Scheduler regelmäßig überprüfen, um die Anzahl der zu erledigenden Aufgaben zu bestimmen.

Dies ist eine Linux-Funktion in (aus Wikipedia gerippt), die diese Berechnung durchführt :

#define FSHIFT   11  /* nr of bits of precision */
#define FIXED_1  (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1  1884  /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5  2014  /* 1/exp(5sec/5min) */
#define EXP_15 2037  /* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
    load *= exp; \
    load += n*(FIXED_1-exp); \
    load >>= FSHIFT;

unsigned long avenrun[3];

static inline void calc_load(unsigned long ticks)
{
    unsigned long active_tasks; /* fixed-point */
    static int count = LOAD_FREQ;

    count -= ticks;
    if (count < 0) {
        count += LOAD_FREQ;
        active_tasks = count_active_tasks();
        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
    }
}

Was den zweiten Teil Ihrer Frage betrifft, sind die meisten modernen Betriebssysteme multitaskingfähig . Das bedeutet, dass das Betriebssystem nicht zulässt, dass Programme die gesamte Verarbeitungszeit in Anspruch nehmen und keine für sich selbst haben (es sei denn, Sie lassen dies tun) . Mit anderen Worten, selbst wenn eine Anwendung hängen bleibt , kann das Betriebssystem noch einige Zeit für seine eigene Arbeit stehlen.

In silico
quelle
3
"Die CPU selbst führt tatsächlich keine Berechnungen der CPU-Auslastung durch." - Wo wird der Betriebssystemcode ausgeführt, der die Arbeitslast auf dem Prozessor abtastet? :)
Ani
2
@Ani: Nun, die CPU kann ohne Code nichts alleine machen, oder? :-) Ich meinte damit, dass es keinen Opcode oder Maschinenbefehl gibt, der Ihnen die CPU-Auslastung angibt, AFAIK.
In silico
@aaa Karpfen: Ah, das ist interessant, ich stehe korrigiert. Obwohl ich mir ziemlich sicher bin, dass das Betriebssystem die (Gesamt-) CPU-Auslastung immer noch anhand der Leistungsindikatoren berechnen muss.
In silico
Sicher, Sie müssen sie noch verarbeiten, es sind nur Zahlen im Register. Leistungsindikatoren geben ziemlich gute Informationen, die das Betriebssystem möglicherweise nicht hat, z. B. Cache-
Fehler
2
@Vatine: Ich habe die Frage des OP so interpretiert, dass sie mit der CPU-Auslastung zu tun hat, da in der Frage die Leistung erwähnt wird. Wenn CPU A 2 ausstehende Aufgaben hat, während CPU B 20 ausstehende Aufgaben hat (beide führen ähnliche Aufgaben aus), verbrauchen beide möglicherweise 100% der CPU-Zeit, aber CPU A arbeitet besser.
In Silico
68

Es gibt eine spezielle Aufgabe, die als Leerlaufaufgabe bezeichnet wird und ausgeführt wird, wenn keine andere Aufgabe ausgeführt werden kann. Die prozentuale Nutzung ist nur der Prozentsatz der Zeit, in der wir die Leerlaufaufgabe nicht ausführen. Das Betriebssystem behält die gesamte Zeit für die Ausführung der Leerlaufaufgabe bei:

  • Wenn wir zur Leerlaufaufgabe wechseln, setzen Sie t = aktuelle Zeit
  • Wenn wir von der Leerlaufaufgabe wegschalten, addieren Sie (aktuelle Zeit - t) zur laufenden Summe

Wenn wir zwei Stichproben der laufenden Gesamtzahl von n Sekunden auseinander nehmen, können wir den Prozentsatz der n Sekunden, die für die Ausführung der Leerlaufaufgabe aufgewendet wurden, als (zweite Stichprobe - erste Stichprobe) / n berechnen

Beachten Sie, dass dies vom Betriebssystem und nicht von der CPU ausgeführt wird. Das Konzept einer Aufgabe existiert auf CPU-Ebene nicht! (In der Praxis versetzt die Leerlaufaufgabe den Prozessor mit einem HLT-Befehl in den Ruhezustand, sodass die CPU weiß, wann er nicht verwendet wird.)

Was die zweite Frage betrifft, sind moderne Betriebssysteme präventiv multitaskingfähig, was bedeutet, dass das Betriebssystem jederzeit von Ihrer Aufgabe abweichen kann. Wie stiehlt das Betriebssystem die CPU tatsächlich von Ihrer Aufgabe? Interrupts: http://en.wikipedia.org/wiki/Interrupt

Dave
quelle
12
++ Hervorragende Antwort. Ich sage den Leuten auch, dass Programme entweder ausgeführt werden oder warten und 100% bzw. 0% des Kerns verwenden. Die "% Auslastung", die sie sehen, ist nur ein kurzer laufender Durchschnitt. Sie würden denken, das wäre offensichtlich, aber manchmal ist es nicht.
Mike Dunlavey
1
+1 Das erklärt alles kurz, danke! Es ist gut zu wissen, dass es der CPU tatsächlich möglich ist, mit dem HLT-Befehl und den Interrupts "nichts zu tun".
Tjklemz
@tjklemz: Unterhaltsame Tatsache: Modernes x86 wechselt mit speziellen Argumenten für monitor/ mwaitAnweisungen in den Ruhezustand . hltspart etwas Strom, aber nur den flachsten Schlafzustand (C1) . Verwandte: software.intel.com/en-us/blogs/2008/03/27/… / software.intel.com/en-us/blogs/2008/04/29/… . Beachten Sie, dass Skylake es dem Betriebssystem endlich ermöglicht, die volle Kontrolle an die Hardware zu übergeben, zumindest für die Frequenzskalierung, während es aktiv ist, aber möglicherweise entscheidet das Betriebssystem immer noch über den Ruhezustand.
Peter Cordes
16

Um die CPU-Auslastung zu ermitteln, überprüfen Sie regelmäßig die Gesamtprozesszeit und ermitteln Sie den Unterschied.

Wenn dies beispielsweise die CPU-Zeiten für Prozess 1 sind:

kernel: 1:00:00.0000
user:   9:00:00.0000

Und dann erhalten Sie sie zwei Sekunden später wieder und sie sind:

kernel: 1:00:00.0300
user:   9:00:00.6100

Sie subtrahieren die Kernelzeiten (für einen Unterschied von 0.03) und die Benutzerzeiten ( 0.61), addieren sie ( 0.64) und dividieren durch die Abtastzeit von 2 Sekunden ( 0.32).

In den letzten zwei Sekunden verbrauchte der Prozess durchschnittlich 32% der CPU-Zeit.

Die spezifischen Systemaufrufe, die zum Abrufen dieser Informationen erforderlich sind, sind (offensichtlich) auf jeder Plattform unterschiedlich. Unter Windows können Sie GetProcessTimes oder GetSystemTimes verwenden, wenn Sie eine Verknüpfung zur gesamten verwendeten oder nicht genutzten CPU-Zeit wünschen .

zildjohn01
quelle
8

Ein Weg, dies zu tun, ist wie folgt:

Wählen Sie ein Abtastintervall, beispielsweise alle 5 Minuten (300 Sekunden) der tatsächlich verstrichenen Zeit. Sie können dies von bekommen gettimeofday.

Holen Sie sich die Prozesszeit, die Sie in diesen 300 Sekunden verwendet haben. Sie können den times()Anruf verwenden, um dies zu erhalten. Das wäre die new_process_time - old_process_time, wo old_process_timeist die Prozesszeit, die Sie aus dem letzten Zeitintervall gespeichert haben.

Ihr CPU-Prozentsatz ist dann (process_time/elapsed_time)*100.0 Sie können einen Alarm einstellen, der Sie alle 300 Sekunden signalisiert, um diese Berechnungen durchzuführen.

Ich habe einen Prozess, bei dem ich nicht mehr als einen bestimmten Ziel-CPU-Prozentsatz verwenden möchte. Diese Methode funktioniert ziemlich gut und stimmt gut mit meinem Systemmonitor überein. Wenn wir zu viel CPU verwenden, schlafen wir ein wenig.

user1725779
quelle
2

Dies ist mein Grundverständnis, wenn ich ein wenig mit ähnlichem Code in Berührung komme. Programme wie der Task-Manager oder Ihr Widget-Zugriffssystem rufen NtQuerySystemInformation () auf und verwenden die vom Betriebssystem gesammelten Informationen, um auf einfache Weise den Prozentsatz der Zeit zu berechnen, in der eine CPU inaktiv ist oder verwendet wird (in einer Standardzeit). Eine CPU weiß, wann sie inaktiv ist, und kann daher feststellen, wann sie nicht inaktiv ist. Diese Programme können in der Tat verstopfen ... Der Task-Manager meines miesen Laptops friert bei der Berechnung der CPU-Auslastung ständig ein, wenn er zu 100% aufgestockt wird.

Auf der MSDN-Website finden Sie einen coolen Beispielcode, der Funktionsaufrufe zur Berechnung der CPU-Auslastung für eine Reihe von Anweisungen zeigt: http://msdn.microsoft.com/en-us/library/aa364157(VS.85).aspx

Ich glaube, diese Systemaufrufe greifen auf den Kernel-Code zu, der über meinen Rahmen hinausgeht.

AndyG
quelle
2

Es gibt verschiedene Möglichkeiten, dies zu tun:

Der Prozessor verwaltet mehrere Zähler, die die Leistung messen. Sie können über die Papi-Schnittstelle darauf zugreifen. Hier ist zum Beispiel eine kurze Einführung: http://blogs.oracle.com/jonh/entry/performance_counter_generic_events

auch: http://www.drdobbs.com/tools/184406109

Der Zähler, den Sie möglicherweise möchten, ist PAPI_TOT_CYC. Dies ist die Anzahl der belegten Zyklen (wenn ich mich richtig erinnere).

Anycorn
quelle
1

Soweit ich weiß, gibt es einen Riesen

while(true){}

Schleife, die das Betriebssystem hochfährt. Ihr Prozess wird innerhalb dieser Schleife verwaltet. Damit kann externer Code in Blöcken direkt auf dem Prozessor ausgeführt werden. Ohne zu viel zu übertreiben, ist dies eine übermäßige Vereinfachung dessen, was tatsächlich vor sich geht.

Gleno
quelle
0
  1. Die CPU wird nicht "aufgehängt", sondern arbeitet einfach mit maximaler Kapazität, was bedeutet, dass sie jede Sekunde so viele Befehle verarbeitet, wie sie physisch in der Lage ist. Der Prozess, der die CPU-Auslastung berechnet, sind einige dieser Anweisungen. Wenn Anwendungen versuchen, Operationen schneller auszuführen, als die CPU in der Lage ist, werden sie einfach verzögert, daher das "Auflegen".

  2. Die Berechnung der CPU-Auslastung basiert auf der insgesamt verfügbaren Auslastung. Wenn eine CPU also zwei Kerne hat und ein Kern 30% und der andere 60% ausgelastet ist, beträgt die Gesamtauslastung 45%. Sie können auch die Verwendung jedes einzelnen Kerns sehen.

Aashishkebab
quelle