none
CPU-Last ermitteln RRS feed

  • Frage

  • Ich möchte die CPU-Last gesammt und für jeden Kern einzeln ermitteln. Dazu habe ich Folgende Funktion geschrieben:
    private PerformanceCounter performance = new PerformanceCounter();
    
    // Core = -1 => Total
    public float GetProcessorPerformance(int Core)
    {
        performance.CategoryName = "Processor";
        performance.CounterName = "% Processor Time";
        performance.InstanceName = "_Total";
        if (Core != -1)
        {
            performance.InstanceName = Core.ToString();
        }
        return performance.NextValue();
    }
    
    wenn ich nun in meiner main-Funktion die Werte abrufe kommt jedoch immer 0, oder ca. jedes 20. mal 100 heraus. Woran liegt das?
    Koopakiller - http://koopakiller.ko.ohost.de/
    Freitag, 16. Dezember 2011 23:06

Antworten

  • Ich möchte die CPU-Last gesammt und für jeden Kern einzeln ermitteln. Dazu habe ich Folgende Funktion geschrieben:
    private PerformanceCounter performance = new PerformanceCounter();
    
    // Core = -1 => Total
    public float GetProcessorPerformance(int Core)
    {
        performance.CategoryName = "Processor";
        performance.CounterName = "% Processor Time";
        performance.InstanceName = "_Total";
        if (Core != -1)
        {
            performance.InstanceName = Core.ToString();
        }
        return performance.NextValue();
    }
    

    Hi,

    Der erste Aufruf von performance.NextValue(); gibt immer 0 zurück.

    Besser so:

        var tmp = performance.NextValue();
        System.Threading.Thread.Sleep(500);
        return performance.NextValue();
    
    Gruß, Ulf
    Samstag, 17. Dezember 2011 14:23
  • Grüße Koopakiller.

    Ulf hat rechts, aber Sleep ist vielleicht nicht die beste Lösung.

    Ich vorschlage...

    private PerformanceCounter performanceTotal = new PerformanceCounter();
    private List<PerformanceCounter> performanceCores = new List<PerformanceCounter>();
    
    // Ruf in dem Konstructor auf.
    void InitialisePerformanceCounters(int nCores)
    {
        performanceToTal.CategoryName = "Processor";
        performanceTotal.CounterName = "% Processor Time";
        performanceTotal.InstanceName = "_Total";
        performanceTotal.NextValue(); // Der zaehlen starten.
    
        for(int i = 0; i < nCores; i++)
        {
           PerformanceCounter performance = new PerformanceCounter();
           performance.CategoryName = "Processor";
           performance.CounterName = "% Processor Time";
           performance.InstanceName = i.ToString();
           performance.NextValue(); // Der zaehlen starten.
           performanceCores.Add(performance);
        }
    }
    
    
    
    // Core = -1 => Total
    public float GetProcessorPerformance(int Core)
    {
        if (Core == -1)
            return performanceTotal.NextValue()
        else 
           return performanceCores[Core].NextValue();
    }

     

     


    Sonntag, 18. Dezember 2011 00:52
  • Hallo K.,

    Aus der Dokumentation zu NextValue:

    "Wenn der berechnete Wert eines Zählers von zwei Zählerlesevorgängen abhängt, gibt der erste Lesevorgang 0,0 zurück. Das Zurücksetzen der Leistungsindikatoreigenschaften, um einen anderen Indikator anzugeben, entspricht dem Erstellen eines neuen Leistungsindikators, und beim ersten Lesevorgang mit den neuen Eigenschaften wird 0,0 zurückgegeben."

    Mit anderen Worten: "it's by design". Da beim ersten Aufruf von NextValue nur das aktuelle Sample existiert (es wurden ja noch keine Altdaten gesampelt), geht das auch nicht anders.

    Edit: Vielleicht einige Erklärungen noch. Der PerformanceCounter, den Du erstellst ist vom Typ Timer100Ns. Bei diesem Typ erfolgen die Berechnungen lt. Dokumentation folgendermaßen:

    "Ein Prozentindikator, der die Aktivitätsdauer einer Komponente als prozentualen Anteil der Gesamtdauer des Messintervalls darstellt. Die Zeit wird dabei in Einheiten von 100 Nanosekunden (ns) gemessen. Zeiger dieses Typs sind zur Messung der Aktivität einer einzelnen Komponente vorgesehen. Formel: (N1-N0)/(D1-D0) x 100, wobei der Zähler den Anteil des Messintervalls, innerhalb dessen die überwachten Komponenten aktiv waren, und der Nenner die Gesamtdauer des Messintervalls darstellt. Zu den Indikatoren dieses Typs gehört Prozessor\ Benutzerzeit (%)."

    Der Formel kann man leicht entnehmen, dass von N1 der Wert von N0 subtrahiert wird. Da N0 - wie oben erwähnt - beim ersten Lesen noch gar nicht existiert, wird eben 0 zurückgegeben.

    BCL Team Blog, Ryan Byington - How to Read Performance Counters:
    http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx

    BCL Team Blog, Ravi Krishnaswamy - How to find CPU usage of a process?
    http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx

    Gruß
    Marcel


    Sonntag, 18. Dezember 2011 17:26
    Moderator

Alle Antworten

  • Ich möchte die CPU-Last gesammt und für jeden Kern einzeln ermitteln. Dazu habe ich Folgende Funktion geschrieben:
    private PerformanceCounter performance = new PerformanceCounter();
    
    // Core = -1 => Total
    public float GetProcessorPerformance(int Core)
    {
        performance.CategoryName = "Processor";
        performance.CounterName = "% Processor Time";
        performance.InstanceName = "_Total";
        if (Core != -1)
        {
            performance.InstanceName = Core.ToString();
        }
        return performance.NextValue();
    }
    

    Hi,

    Der erste Aufruf von performance.NextValue(); gibt immer 0 zurück.

    Besser so:

        var tmp = performance.NextValue();
        System.Threading.Thread.Sleep(500);
        return performance.NextValue();
    
    Gruß, Ulf
    Samstag, 17. Dezember 2011 14:23
  • Grüße Koopakiller.

    Ulf hat rechts, aber Sleep ist vielleicht nicht die beste Lösung.

    Ich vorschlage...

    private PerformanceCounter performanceTotal = new PerformanceCounter();
    private List<PerformanceCounter> performanceCores = new List<PerformanceCounter>();
    
    // Ruf in dem Konstructor auf.
    void InitialisePerformanceCounters(int nCores)
    {
        performanceToTal.CategoryName = "Processor";
        performanceTotal.CounterName = "% Processor Time";
        performanceTotal.InstanceName = "_Total";
        performanceTotal.NextValue(); // Der zaehlen starten.
    
        for(int i = 0; i < nCores; i++)
        {
           PerformanceCounter performance = new PerformanceCounter();
           performance.CategoryName = "Processor";
           performance.CounterName = "% Processor Time";
           performance.InstanceName = i.ToString();
           performance.NextValue(); // Der zaehlen starten.
           performanceCores.Add(performance);
        }
    }
    
    
    
    // Core = -1 => Total
    public float GetProcessorPerformance(int Core)
    {
        if (Core == -1)
            return performanceTotal.NextValue()
        else 
           return performanceCores[Core].NextValue();
    }

     

     


    Sonntag, 18. Dezember 2011 00:52
  • Danke für die Antworten!

    OK, es geht jetzt erstmal, aber kann mir noch jemand erklären warum beim 1. Aufruf von performance.NextValue() immer 0 heraus kommt?


    Koopakiller - http://koopakiller.ko.ohost.de/
    Sonntag, 18. Dezember 2011 16:21
  • Hallo K.,

    Aus der Dokumentation zu NextValue:

    "Wenn der berechnete Wert eines Zählers von zwei Zählerlesevorgängen abhängt, gibt der erste Lesevorgang 0,0 zurück. Das Zurücksetzen der Leistungsindikatoreigenschaften, um einen anderen Indikator anzugeben, entspricht dem Erstellen eines neuen Leistungsindikators, und beim ersten Lesevorgang mit den neuen Eigenschaften wird 0,0 zurückgegeben."

    Mit anderen Worten: "it's by design". Da beim ersten Aufruf von NextValue nur das aktuelle Sample existiert (es wurden ja noch keine Altdaten gesampelt), geht das auch nicht anders.

    Edit: Vielleicht einige Erklärungen noch. Der PerformanceCounter, den Du erstellst ist vom Typ Timer100Ns. Bei diesem Typ erfolgen die Berechnungen lt. Dokumentation folgendermaßen:

    "Ein Prozentindikator, der die Aktivitätsdauer einer Komponente als prozentualen Anteil der Gesamtdauer des Messintervalls darstellt. Die Zeit wird dabei in Einheiten von 100 Nanosekunden (ns) gemessen. Zeiger dieses Typs sind zur Messung der Aktivität einer einzelnen Komponente vorgesehen. Formel: (N1-N0)/(D1-D0) x 100, wobei der Zähler den Anteil des Messintervalls, innerhalb dessen die überwachten Komponenten aktiv waren, und der Nenner die Gesamtdauer des Messintervalls darstellt. Zu den Indikatoren dieses Typs gehört Prozessor\ Benutzerzeit (%)."

    Der Formel kann man leicht entnehmen, dass von N1 der Wert von N0 subtrahiert wird. Da N0 - wie oben erwähnt - beim ersten Lesen noch gar nicht existiert, wird eben 0 zurückgegeben.

    BCL Team Blog, Ryan Byington - How to Read Performance Counters:
    http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx

    BCL Team Blog, Ravi Krishnaswamy - How to find CPU usage of a process?
    http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx

    Gruß
    Marcel


    Sonntag, 18. Dezember 2011 17:26
    Moderator