mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-01 06:45:12 +00:00
Added support for Intel CPU power sensors (package and cores).
This commit is contained in:
@@ -65,6 +65,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
typeNodes.Add(new TypeNode(SensorType.Flow));
|
||||
typeNodes.Add(new TypeNode(SensorType.Control));
|
||||
typeNodes.Add(new TypeNode(SensorType.Level));
|
||||
typeNodes.Add(new TypeNode(SensorType.Power));
|
||||
|
||||
foreach (ISensor sensor in hardware.Sensors)
|
||||
SensorAdded(sensor);
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
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.
|
||||
|
||||
Contributor(s):
|
||||
@@ -75,6 +75,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
case SensorType.Flow: format = "{0:F0} L/h"; break;
|
||||
case SensorType.Control: 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,
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
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.
|
||||
|
||||
Contributor(s):
|
||||
@@ -196,6 +196,8 @@ namespace OpenHardwareMonitor.GUI {
|
||||
return string.Format("{0:F0}", sensor.Value);
|
||||
case SensorType.Level:
|
||||
return string.Format("{0:F0}", sensor.Value);
|
||||
case SensorType.Power:
|
||||
return string.Format("{0:F0}", sensor.Value);
|
||||
}
|
||||
return "-";
|
||||
}
|
||||
@@ -283,6 +285,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
|
||||
case SensorType.Control: 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 hardwareName = sensor.Hardware.Name;
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
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.
|
||||
|
||||
Contributor(s):
|
||||
@@ -80,6 +80,10 @@ namespace OpenHardwareMonitor.GUI {
|
||||
this.Image = Utilities.EmbeddedResources.GetImage("level.png");
|
||||
this.Text = "Levels";
|
||||
break;
|
||||
case SensorType.Power:
|
||||
this.Image = Utilities.EmbeddedResources.GetImage("power.png");
|
||||
this.Text = "Powers";
|
||||
break;
|
||||
}
|
||||
|
||||
NodeAdded += new NodeEventHandler(TypeNode_NodeAdded);
|
||||
|
@@ -55,6 +55,8 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
private readonly Sensor packageTemperature;
|
||||
private readonly Sensor[] coreClocks;
|
||||
private readonly Sensor busClock;
|
||||
private readonly Sensor packagePower;
|
||||
private readonly Sensor coresPower;
|
||||
|
||||
private readonly Microarchitecture microarchitecture;
|
||||
private readonly double timeStampCounterMultiplier;
|
||||
@@ -64,6 +66,17 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
private const uint IA32_PERF_STATUS = 0x0198;
|
||||
private const uint MSR_PLATFORM_INFO = 0xCE;
|
||||
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) {
|
||||
float[] result = new float[coreCount];
|
||||
@@ -242,6 +255,33 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -251,7 +291,10 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
IA32_PERF_STATUS ,
|
||||
IA32_THERM_STATUS_MSR,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
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.
|
||||
|
||||
Contributor(s):
|
||||
@@ -49,7 +49,8 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
Fan,
|
||||
Flow,
|
||||
Control,
|
||||
Level
|
||||
Level,
|
||||
Power
|
||||
}
|
||||
|
||||
public struct SensorValue {
|
||||
|
@@ -217,6 +217,9 @@
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\level.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\power.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio AllowExistingFolder="true" />
|
||||
|
BIN
Resources/power.png
Normal file
BIN
Resources/power.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 293 B |
Reference in New Issue
Block a user