Hardware/CPU/IntelCPU.cs
changeset 317 1ccf99e620a9
parent 315 158ec57434e8
child 320 df3493f75225
     1.1 --- a/Hardware/CPU/IntelCPU.cs	Mon Jul 25 21:09:21 2011 +0000
     1.2 +++ b/Hardware/CPU/IntelCPU.cs	Wed Jul 27 18:27:16 2011 +0000
     1.3 @@ -55,6 +55,8 @@
     1.4      private readonly Sensor packageTemperature;
     1.5      private readonly Sensor[] coreClocks;
     1.6      private readonly Sensor busClock;
     1.7 +    private readonly Sensor packagePower;
     1.8 +    private readonly Sensor coresPower;
     1.9  
    1.10      private readonly Microarchitecture microarchitecture;
    1.11      private readonly double timeStampCounterMultiplier;
    1.12 @@ -64,6 +66,17 @@
    1.13      private const uint IA32_PERF_STATUS = 0x0198;
    1.14      private const uint MSR_PLATFORM_INFO = 0xCE;
    1.15      private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1;
    1.16 +    private const uint MSR_RAPL_POWER_UNIT = 0x606;
    1.17 +    private const uint MSR_PKG_ENERY_STATUS = 0x611;
    1.18 +    private const uint MSR_PP0_ENERY_STATUS = 0x639;
    1.19 +
    1.20 +    private float energyUnitMultiplier = 0;
    1.21 +    private DateTime lastPackageTime;
    1.22 +    private uint lastPackageEnergyConsumed;
    1.23 +    private DateTime lastCoresTime;
    1.24 +    private uint lastCoresEnergyConsumed;
    1.25 +
    1.26 +
    1.27  
    1.28      private float[] Floats(float f) {
    1.29        float[] result = new float[coreCount];
    1.30 @@ -242,6 +255,33 @@
    1.31            ActivateSensor(coreClocks[i]);
    1.32        }
    1.33  
    1.34 +      if (microarchitecture == Microarchitecture.SandyBridge) {
    1.35 +        uint eax, edx;
    1.36 +        if (Ring0.Rdmsr(MSR_RAPL_POWER_UNIT, out eax, out edx))
    1.37 +          energyUnitMultiplier = 1.0f / (1 << (int)((eax >> 8) & 0x1FF));
    1.38 +
    1.39 +
    1.40 +        if (energyUnitMultiplier != 0 && 
    1.41 +          Ring0.Rdmsr(MSR_PKG_ENERY_STATUS, out eax, out edx)) 
    1.42 +        {
    1.43 +          lastPackageTime = DateTime.UtcNow;
    1.44 +          lastPackageEnergyConsumed = eax;
    1.45 +          packagePower = new Sensor("CPU Package", 0, SensorType.Power, this, 
    1.46 +            settings);          
    1.47 +          ActivateSensor(packagePower);
    1.48 +        }
    1.49 +
    1.50 +        if (energyUnitMultiplier != 0 &&
    1.51 +          Ring0.Rdmsr(MSR_PP0_ENERY_STATUS, out eax, out edx)) 
    1.52 +        {
    1.53 +          lastCoresTime = DateTime.UtcNow;
    1.54 +          lastCoresEnergyConsumed = eax;
    1.55 +          coresPower = new Sensor("CPU Cores", 1, SensorType.Power, this,
    1.56 +            settings);
    1.57 +          ActivateSensor(coresPower);
    1.58 +        }
    1.59 +      }
    1.60 +
    1.61        Update();
    1.62      }
    1.63  
    1.64 @@ -251,7 +291,10 @@
    1.65          IA32_PERF_STATUS ,
    1.66          IA32_THERM_STATUS_MSR,
    1.67          IA32_TEMPERATURE_TARGET,
    1.68 -        IA32_PACKAGE_THERM_STATUS
    1.69 +        IA32_PACKAGE_THERM_STATUS,
    1.70 +        MSR_RAPL_POWER_UNIT,
    1.71 +        MSR_PKG_ENERY_STATUS,
    1.72 +        MSR_PP0_ENERY_STATUS
    1.73        };
    1.74      }
    1.75  
    1.76 @@ -340,6 +383,37 @@
    1.77            ActivateSensor(this.busClock);
    1.78          }
    1.79        }
    1.80 +
    1.81 +
    1.82 +      if (packagePower != null) {
    1.83 +        uint eax, edx;
    1.84 +        if (Ring0.Rdmsr(MSR_PKG_ENERY_STATUS, out eax, out edx)) {
    1.85 +          DateTime time = DateTime.UtcNow;    
    1.86 +          uint energyConsumed = eax;
    1.87 +          float deltaTime = (float)(time - lastPackageTime).TotalSeconds;
    1.88 +          if (deltaTime > 0.01) {
    1.89 +            packagePower.Value = energyUnitMultiplier * 
    1.90 +              unchecked(energyConsumed - lastPackageEnergyConsumed) / deltaTime;
    1.91 +            lastPackageTime = time;
    1.92 +            lastPackageEnergyConsumed = energyConsumed;
    1.93 +          }
    1.94 +        }         
    1.95 +      }
    1.96 +
    1.97 +      if (coresPower != null) {
    1.98 +        uint eax, edx;
    1.99 +        if (Ring0.Rdmsr(MSR_PP0_ENERY_STATUS, out eax, out edx)) {
   1.100 +          DateTime time = DateTime.UtcNow;
   1.101 +          uint energyConsumed = eax;
   1.102 +          float deltaTime = (float)(time - lastCoresTime).TotalSeconds;
   1.103 +          if (deltaTime > 0.01) {
   1.104 +            coresPower.Value = energyUnitMultiplier *
   1.105 +              unchecked(energyConsumed - lastCoresEnergyConsumed) / deltaTime;
   1.106 +            lastCoresTime = time;
   1.107 +            lastCoresEnergyConsumed = energyConsumed;
   1.108 +          }
   1.109 +        }
   1.110 +      }
   1.111      }
   1.112    }
   1.113  }