Improved the CPU load sensors. The values displayed for the load per core and the total load should now be more accurate.
authormoel.mich
Sun, 24 Jul 2011 16:18:56 +0000
changeset 313596df85bb4e1
parent 312 35fb76b88d94
child 314 d19c6b4d625e
Improved the CPU load sensors. The values displayed for the load per core and the total load should now be more accurate.
Hardware/CPU/CPULoad.cs
     1.1 --- a/Hardware/CPU/CPULoad.cs	Sun Jul 24 12:17:17 2011 +0000
     1.2 +++ b/Hardware/CPU/CPULoad.cs	Sun Jul 24 16:18:56 2011 +0000
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5    The Initial Developer of the Original Code is 
     1.6    Michael Möller <m.moeller@gmx.ch>.
     1.7 -  Portions created by the Initial Developer are Copyright (C) 2009-2010
     1.8 +  Portions created by the Initial Developer are Copyright (C) 2009-2011
     1.9    the Initial Developer. All Rights Reserved.
    1.10  
    1.11    Contributor(s):
    1.12 @@ -62,43 +62,49 @@
    1.13  
    1.14      private readonly CPUID[][] cpuid;
    1.15  
    1.16 -    private long systemTime;
    1.17      private long[] idleTimes;
    1.18 +    private long[] totalTimes;
    1.19  
    1.20      private float totalLoad;
    1.21      private readonly float[] coreLoads;
    1.22  
    1.23      private readonly bool available;
    1.24  
    1.25 -    private static long[] GetIdleTimes() {      
    1.26 +    private static bool GetTimes(out long[] idle, out long[] total) {      
    1.27        SystemProcessorPerformanceInformation[] informations = new
    1.28          SystemProcessorPerformanceInformation[64];
    1.29  
    1.30        int size = Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation));
    1.31  
    1.32 +      idle = null;
    1.33 +      total = null;
    1.34 +
    1.35        IntPtr returnLength;
    1.36        if (NativeMethods.NtQuerySystemInformation(
    1.37          SystemInformationClass.SystemProcessorPerformanceInformation,
    1.38          informations, informations.Length * size, out returnLength) != 0)
    1.39 -        return null;
    1.40 +        return false;
    1.41  
    1.42 -      long[] result = new long[(int)returnLength / size];
    1.43 +      idle = new long[(int)returnLength / size];
    1.44 +      total = new long[(int)returnLength / size];
    1.45  
    1.46 -      for (int i = 0; i < result.Length; i++)
    1.47 -        result[i] = informations[i].IdleTime;
    1.48 +      for (int i = 0; i < idle.Length; i++) {
    1.49 +        idle[i] = informations[i].IdleTime;
    1.50 +        total[i] = informations[i].KernelTime + informations[i].UserTime;
    1.51 +      }
    1.52  
    1.53 -      return result;
    1.54 +      return true;
    1.55      }
    1.56  
    1.57      public CPULoad(CPUID[][] cpuid) {
    1.58        this.cpuid = cpuid;
    1.59        this.coreLoads = new float[cpuid.Length];         
    1.60 -      this.systemTime = DateTime.Now.Ticks;
    1.61        this.totalLoad = 0;
    1.62        try {
    1.63 -        this.idleTimes = GetIdleTimes();
    1.64 +        GetTimes(out idleTimes, out totalTimes);
    1.65        } catch (Exception) {
    1.66          this.idleTimes = null;
    1.67 +        this.totalTimes = null;
    1.68        }
    1.69        if (idleTimes != null)
    1.70          available = true;
    1.71 @@ -120,13 +126,17 @@
    1.72        if (this.idleTimes == null)
    1.73          return;
    1.74  
    1.75 -      long newSystemTime = DateTime.Now.Ticks;
    1.76 -      long[] newIdleTimes = GetIdleTimes();
    1.77 +      long[] newIdleTimes;
    1.78 +      long[] newTotalTimes;
    1.79  
    1.80 -      if (newSystemTime - this.systemTime < 10000)
    1.81 +      if (!GetTimes(out newIdleTimes, out newTotalTimes))
    1.82          return;
    1.83  
    1.84 -      if (newIdleTimes == null)
    1.85 +      for (int i = 0; i < Math.Min(newTotalTimes.Length, totalTimes.Length); i++) 
    1.86 +        if (newTotalTimes[i] - this.totalTimes[i] < 100000)
    1.87 +          return;
    1.88 +
    1.89 +      if (newIdleTimes == null || newTotalTimes == null)
    1.90          return;
    1.91  
    1.92        float total = 0;
    1.93 @@ -135,27 +145,28 @@
    1.94          float value = 0;
    1.95          for (int j = 0; j < cpuid[i].Length; j++) {
    1.96            long index = cpuid[i][j].Thread;
    1.97 -          if (index < newIdleTimes.Length) {
    1.98 -            long delta = newIdleTimes[index] - this.idleTimes[index];
    1.99 -            value += delta;
   1.100 -            total += delta;
   1.101 +          if (index < newIdleTimes.Length && index < totalTimes.Length) {
   1.102 +            float idle = 
   1.103 +              (float)(newIdleTimes[index] - this.idleTimes[index]) /
   1.104 +              (float)(newTotalTimes[index] - this.totalTimes[index]);
   1.105 +            value += idle;
   1.106 +            total += idle;
   1.107              count++;
   1.108            }
   1.109          }
   1.110 -        value = 1.0f - value / (cpuid[i].Length * 
   1.111 -          (newSystemTime - this.systemTime));
   1.112 +        value = 1.0f - value / cpuid[i].Length;
   1.113          value = value < 0 ? 0 : value;
   1.114          coreLoads[i] = value * 100;
   1.115        }
   1.116        if (count > 0) {
   1.117 -        total = 1.0f - total / (count * (newSystemTime - this.systemTime));
   1.118 +        total = 1.0f - total / count;
   1.119          total = total < 0 ? 0 : total;
   1.120        } else {
   1.121          total = 0;
   1.122        }
   1.123        this.totalLoad = total * 100;
   1.124  
   1.125 -      this.systemTime = newSystemTime;
   1.126 +      this.totalTimes = newTotalTimes;
   1.127        this.idleTimes = newIdleTimes;
   1.128      }
   1.129