it-swarm.com.de

Wie wird die CPU-Auslastung berechnet?

Auf meinem Desktop habe ich ein kleines Widget, das mir meine aktuelle CPU-Auslastung anzeigt. Es zeigt auch die Verwendung für jeden meiner zwei 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 dabei aufgehängt zu werden?

63
Chris Laplante

Die CPU führt die Nutzungsberechnungen nicht alleine durch. Möglicherweise verfügt es über Hardwarefunktionen, um diese Aufgabe zu vereinfachen. Dies ist jedoch hauptsächlich Aufgabe des Betriebssystems. Daher variieren natürlich die Details der Implementierungen (insbesondere im Fall von Multicore-Systemen).

Die allgemeine Idee ist, zu sehen, wie lange die CPU in der Warteschlange warten muss. Das Betriebssystem kann in regelmäßigen Abständen einen Blick auf den Scheduler werfen, um die Anzahl der zu erledigenden Aufgaben zu bestimmen.

Dies ist eine Funktion in Linux (aus Wikipedia rippen), die die 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 Multi-Tasked . 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 veranlassen dies) . Mit anderen Worten, auch wenn eine Anwendung hängen bleibt, kann das Betriebssystem immer noch etwas Zeit für seine eigene Arbeit wegnehmen.

29
In silico

Es gibt eine spezielle Task namens Leerlauf-Task, die ausgeführt wird, wenn keine andere Task ausgeführt werden kann. Die% -Verwendung ist nur der Prozentsatz der Zeit, zu der die Leerlaufaufgabe nicht ausgeführt wird. Das Betriebssystem behält die Gesamtlaufzeit der Leerlaufaufgabe bei:

  • wenn Sie zur Leerlaufaufgabe wechseln, setzen Sie t = aktuelle Uhrzeit
  • wenn Sie von der Leerlaufaufgabe wechseln, addieren Sie (laufende Zeit - t) zur laufenden Summe

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

Beachten Sie, dass dies das Betriebssystem ist, nicht die CPU. Das Konzept einer Aufgabe existiert nicht auf CPU-Ebene! (In der Praxis versetzt die Task im Leerlauf den Prozessor mit einem HLT-Befehl in den Ruhezustand, sodass die CPU weiß, wann sie nicht verwendet wird.)

Bei der zweiten Frage sind moderne Betriebssysteme präemptiv mit mehreren Aufgaben ausgestattet, sodass 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

60
dave

Um die CPU-Auslastung zu erhalten, sollten Sie regelmäßig die total -Prozesszeit abfragen und die Differenz ermitteln.

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

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

Und dann bekommst du 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 eine Differenz von 0.03) und die Benutzerzeiten (0.61), addieren sie zusammen (0.64) und dividieren durch die Abtastzeit von 2 Sekunden (0.32).

In den letzten zwei Sekunden benötigte der Prozess also durchschnittlich 32% CPU-Zeit.

Die spezifischen Systemaufrufe, die erforderlich sind, um diese Informationen abzurufen, unterscheiden sich (offensichtlich) auf jeder Plattform. Unter Windows können Sie GetProcessTimes oder GetSystemTimes verwenden, wenn Sie eine Verknüpfung zu total verbraucht oder die CPU-Zeit im Leerlauf verwenden möchten.

12
zildjohn01

Eine Möglichkeit, dies zu tun, ist wie folgt:

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

Erhalten Sie die Prozesszeit, die Sie in diesen 300 Sekunden verwendet haben. Sie können den Aufruf times() verwenden, um dies zu erhalten. Dies wäre der new_process_time - old_process_time, wobei old_process_time die Verarbeitungszeit ist, die Sie im letzten Zeitintervall gespeichert haben.

Ihr CPU-Prozentsatz lautet dann (process_time/elapsed_time)*100.0 Sie können einen Alarm einstellen, um Sie alle 300 Sekunden zu signalisieren, dass diese Berechnungen durchgeführt werden. 

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

7
user1725779

Dies ist mein grundlegendes Verständnis dafür, dass ich etwas ähnlichen Code kennengelernt habe. Programme wie der Task-Manager oder Ihr Widget greifen auf Systemaufrufe wie NtQuerySystemInformation () zu und verwenden die vom Betriebssystem gesammelten Informationen, um eine einfache Berechnung der Prozentsätze der Zeit durchzuführen, die eine CPU inaktiv ist oder verwendet wird (in einer Standardzeit). Eine CPU weiß, wann sie im Leerlauf ist, und kann daher feststellen, wann sie nicht im Leerlauf ist. Diese Programme können tatsächlich verstopft sein ... Der Task-Manager meines miesen Laptops friert beim Berechnen der CPU-Auslastung ständig ein, wenn er bei 100% liegt. 

Auf der MSDN-Website ist ein cooler Beispielcode zu finden, der Funktionsaufrufe für die Berechnung der CPU-Nutzung für eine Reihe von Anweisungen zeigt: http://msdn.Microsoft.com/de-de/library/aa364157 (VS.85). .aspx

Was diese Systemaufrufe tun, ist Zugriffskernelcode, von dem ich glaube, dass er das nicht versteht.

2
AndyG

es gibt verschiedene Möglichkeiten, wie Sie dies tun können:

Der Prozessor verwaltet mehrere Leistungsindikatoren, auf die Sie über die Papi-Schnittstelle zugreifen können. Zum Beispiel ist hier 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 benötigen, ist PAPI_TOT_CYC. Dies ist die Anzahl der ausgelasteten Zyklen (wenn ich mich recht erinnere)

1
Anycorn

Nun, soweit ich es verstehe, gibt es einen Riesen 

while(true){}

schleife, die die Betriebssysteme anlaufen. Ihr Prozess wird innerhalb dieser Schleife verwaltet. Damit kann externer Code in Chunks 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.

0
Gleno
  1. Die CPU wird nicht "aufgehängt", sie arbeitet einfach mit Spitzenleistung, was bedeutet, dass sie so viele Befehle verarbeitet, wie sie pro Sekunde physisch in der Lage sind ... Der Prozess, der die CPU-Nutzung berechnet, ist einige dieser Anweisungen. Wenn Anwendungen versuchen, Vorgänge schneller auszuführen, als die CPU fähig ist, werden sie einfach verzögert, daher das "Auflegen".

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

0
Aashishkebab