Added support for Intel CPU power sensors (package and cores).

This commit is contained in:
Michael Möller
2011-07-27 18:27:16 +00:00
parent e3adf6ceb6
commit 70c338cc63
8 changed files with 94 additions and 7 deletions

View File

@@ -65,7 +65,8 @@ namespace OpenHardwareMonitor.GUI {
typeNodes.Add(new TypeNode(SensorType.Flow)); typeNodes.Add(new TypeNode(SensorType.Flow));
typeNodes.Add(new TypeNode(SensorType.Control)); typeNodes.Add(new TypeNode(SensorType.Control));
typeNodes.Add(new TypeNode(SensorType.Level)); typeNodes.Add(new TypeNode(SensorType.Level));
typeNodes.Add(new TypeNode(SensorType.Power));
foreach (ISensor sensor in hardware.Sensors) foreach (ISensor sensor in hardware.Sensors)
SensorAdded(sensor); SensorAdded(sensor);

View File

@@ -16,7 +16,7 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>. Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010 Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
@@ -75,6 +75,7 @@ namespace OpenHardwareMonitor.GUI {
case SensorType.Flow: format = "{0:F0} L/h"; break; case SensorType.Flow: format = "{0:F0} L/h"; break;
case SensorType.Control: format = "{0:F1} %"; break; case SensorType.Control: format = "{0:F1} %"; break;
case SensorType.Level: format = "{0:F1} %"; break; case SensorType.Level: format = "{0:F1} %"; break;
case SensorType.Power: format = "{0:F1} W"; break;
} }
bool hidden = settings.GetValue(new Identifier(sensor.Identifier, bool hidden = settings.GetValue(new Identifier(sensor.Identifier,

View File

@@ -16,7 +16,7 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>. Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010 Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
@@ -196,6 +196,8 @@ namespace OpenHardwareMonitor.GUI {
return string.Format("{0:F0}", sensor.Value); return string.Format("{0:F0}", sensor.Value);
case SensorType.Level: case SensorType.Level:
return string.Format("{0:F0}", sensor.Value); return string.Format("{0:F0}", sensor.Value);
case SensorType.Power:
return string.Format("{0:F0}", sensor.Value);
} }
return "-"; return "-";
} }
@@ -283,6 +285,7 @@ namespace OpenHardwareMonitor.GUI {
case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break; case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
case SensorType.Control: format = "\n{0}: {1:F1} %"; break; case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
case SensorType.Level: format = "\n{0}: {1:F1} %"; break; case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
} }
string formattedValue = string.Format(format, sensor.Name, sensor.Value); string formattedValue = string.Format(format, sensor.Name, sensor.Value);
string hardwareName = sensor.Hardware.Name; string hardwareName = sensor.Hardware.Name;

View File

@@ -16,7 +16,7 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>. Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010 Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
@@ -80,6 +80,10 @@ namespace OpenHardwareMonitor.GUI {
this.Image = Utilities.EmbeddedResources.GetImage("level.png"); this.Image = Utilities.EmbeddedResources.GetImage("level.png");
this.Text = "Levels"; this.Text = "Levels";
break; break;
case SensorType.Power:
this.Image = Utilities.EmbeddedResources.GetImage("power.png");
this.Text = "Powers";
break;
} }
NodeAdded += new NodeEventHandler(TypeNode_NodeAdded); NodeAdded += new NodeEventHandler(TypeNode_NodeAdded);

View File

@@ -55,6 +55,8 @@ namespace OpenHardwareMonitor.Hardware.CPU {
private readonly Sensor packageTemperature; private readonly Sensor packageTemperature;
private readonly Sensor[] coreClocks; private readonly Sensor[] coreClocks;
private readonly Sensor busClock; private readonly Sensor busClock;
private readonly Sensor packagePower;
private readonly Sensor coresPower;
private readonly Microarchitecture microarchitecture; private readonly Microarchitecture microarchitecture;
private readonly double timeStampCounterMultiplier; private readonly double timeStampCounterMultiplier;
@@ -64,6 +66,17 @@ namespace OpenHardwareMonitor.Hardware.CPU {
private const uint IA32_PERF_STATUS = 0x0198; private const uint IA32_PERF_STATUS = 0x0198;
private const uint MSR_PLATFORM_INFO = 0xCE; private const uint MSR_PLATFORM_INFO = 0xCE;
private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1; private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1;
private const uint MSR_RAPL_POWER_UNIT = 0x606;
private const uint MSR_PKG_ENERY_STATUS = 0x611;
private const uint MSR_PP0_ENERY_STATUS = 0x639;
private float energyUnitMultiplier = 0;
private DateTime lastPackageTime;
private uint lastPackageEnergyConsumed;
private DateTime lastCoresTime;
private uint lastCoresEnergyConsumed;
private float[] Floats(float f) { private float[] Floats(float f) {
float[] result = new float[coreCount]; float[] result = new float[coreCount];
@@ -242,6 +255,33 @@ namespace OpenHardwareMonitor.Hardware.CPU {
ActivateSensor(coreClocks[i]); ActivateSensor(coreClocks[i]);
} }
if (microarchitecture == Microarchitecture.SandyBridge) {
uint eax, edx;
if (Ring0.Rdmsr(MSR_RAPL_POWER_UNIT, out eax, out edx))
energyUnitMultiplier = 1.0f / (1 << (int)((eax >> 8) & 0x1FF));
if (energyUnitMultiplier != 0 &&
Ring0.Rdmsr(MSR_PKG_ENERY_STATUS, out eax, out edx))
{
lastPackageTime = DateTime.UtcNow;
lastPackageEnergyConsumed = eax;
packagePower = new Sensor("CPU Package", 0, SensorType.Power, this,
settings);
ActivateSensor(packagePower);
}
if (energyUnitMultiplier != 0 &&
Ring0.Rdmsr(MSR_PP0_ENERY_STATUS, out eax, out edx))
{
lastCoresTime = DateTime.UtcNow;
lastCoresEnergyConsumed = eax;
coresPower = new Sensor("CPU Cores", 1, SensorType.Power, this,
settings);
ActivateSensor(coresPower);
}
}
Update(); Update();
} }
@@ -251,7 +291,10 @@ namespace OpenHardwareMonitor.Hardware.CPU {
IA32_PERF_STATUS , IA32_PERF_STATUS ,
IA32_THERM_STATUS_MSR, IA32_THERM_STATUS_MSR,
IA32_TEMPERATURE_TARGET, IA32_TEMPERATURE_TARGET,
IA32_PACKAGE_THERM_STATUS IA32_PACKAGE_THERM_STATUS,
MSR_RAPL_POWER_UNIT,
MSR_PKG_ENERY_STATUS,
MSR_PP0_ENERY_STATUS
}; };
} }
@@ -340,6 +383,37 @@ namespace OpenHardwareMonitor.Hardware.CPU {
ActivateSensor(this.busClock); ActivateSensor(this.busClock);
} }
} }
if (packagePower != null) {
uint eax, edx;
if (Ring0.Rdmsr(MSR_PKG_ENERY_STATUS, out eax, out edx)) {
DateTime time = DateTime.UtcNow;
uint energyConsumed = eax;
float deltaTime = (float)(time - lastPackageTime).TotalSeconds;
if (deltaTime > 0.01) {
packagePower.Value = energyUnitMultiplier *
unchecked(energyConsumed - lastPackageEnergyConsumed) / deltaTime;
lastPackageTime = time;
lastPackageEnergyConsumed = energyConsumed;
}
}
}
if (coresPower != null) {
uint eax, edx;
if (Ring0.Rdmsr(MSR_PP0_ENERY_STATUS, out eax, out edx)) {
DateTime time = DateTime.UtcNow;
uint energyConsumed = eax;
float deltaTime = (float)(time - lastCoresTime).TotalSeconds;
if (deltaTime > 0.01) {
coresPower.Value = energyUnitMultiplier *
unchecked(energyConsumed - lastCoresEnergyConsumed) / deltaTime;
lastCoresTime = time;
lastCoresEnergyConsumed = energyConsumed;
}
}
}
} }
} }
} }

View File

@@ -16,7 +16,7 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>. Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010 Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
@@ -49,7 +49,8 @@ namespace OpenHardwareMonitor.Hardware {
Fan, Fan,
Flow, Flow,
Control, Control,
Level Level,
Power
} }
public struct SensorValue { public struct SensorValue {

View File

@@ -217,6 +217,9 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\level.png" /> <EmbeddedResource Include="Resources\level.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\power.png" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<VisualStudio AllowExistingFolder="true" /> <VisualStudio AllowExistingFolder="true" />

BIN
Resources/power.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B