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 }