From 94c742b22da67864df1044622f20303adca46bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E5=A4=9C?= Date: Tue, 9 Dec 2025 19:16:57 +0800 Subject: [PATCH] [Feature] Show Performance & Efficient Core instead of Core (#2095) * Push * Change Voltages, Temperatures to P/E Core. Use independent counter for P/E Core. --- LibreHardwareMonitorLib/Hardware/CoreType.cs | 8 +++ LibreHardwareMonitorLib/Hardware/Cpu/CpuId.cs | 19 ++++++ .../Hardware/Cpu/IntelCpu.cs | 66 +++++++++++++------ 3 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 LibreHardwareMonitorLib/Hardware/CoreType.cs diff --git a/LibreHardwareMonitorLib/Hardware/CoreType.cs b/LibreHardwareMonitorLib/Hardware/CoreType.cs new file mode 100644 index 0000000..0f83c8f --- /dev/null +++ b/LibreHardwareMonitorLib/Hardware/CoreType.cs @@ -0,0 +1,8 @@ +namespace LibreHardwareMonitor.Hardware; + +public enum CoreType +{ + Unknown = 0, + Performance = 0x40, + Efficient = 0x20 +} diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/CpuId.cs b/LibreHardwareMonitorLib/Hardware/Cpu/CpuId.cs index 5575b8a..785c1e3 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/CpuId.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/CpuId.cs @@ -83,6 +83,24 @@ public class CpuId OpCode.CpuId(CPUID_0 + i, 0, out Data[i, 0], out Data[i, 1], out Data[i, 2], out Data[i, 3]); } + if (Vendor == Vendor.Intel && maxCpuid >= 0x1A) + { + // Leaf 0x1A, SubLeaf 0, EAX Bits 31:24 = Core Type ID + uint coreType = (Data[0x1A, 0] >> 24) & 0xFF; + + CoreType = coreType switch + { + // 0x40 = Core (P-Core), 0x20 = Atom (E-Core) + 0x40 => CoreType.Performance, + 0x20 => CoreType.Efficient, + _ => CoreType.Unknown + }; + } + else + { + CoreType = CoreType.Unknown; + } + ExtData = new uint[maxCpuidExt + 1, 4]; for (uint i = 0; i < maxCpuidExt + 1; i++) { @@ -191,6 +209,7 @@ public class CpuId public string BrandString { get; } = string.Empty; public uint CoreId { get; } + public CoreType CoreType { get; } = CoreType.Unknown; public uint[,] Data { get; } = new uint[0, 0]; diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs index 87cb66d..1f32d1d 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs @@ -23,6 +23,8 @@ internal sealed class IntelCpu : GenericCpu private readonly Sensor _coreVoltage; private readonly Sensor[] _distToTjMaxTemperatures; + private readonly string[] _coreNames; + private readonly uint[] _energyStatusMsrs = { MSR_PKG_ENERGY_STATUS, MSR_PP0_ENERGY_STATUS, MSR_PP1_ENERGY_STATUS, MSR_DRAM_ENERGY_STATUS, MSR_PLATFORM_ENERGY_STATUS }; private readonly uint[] _lastEnergyConsumed; private readonly DateTime[] _lastEnergyTime; @@ -324,6 +326,30 @@ internal sealed class IntelCpu : GenericCpu break; } + // Initialize core names + _coreNames = new string[_coreCount]; + int pCoreIndex = 1; + int eCoreIndex = 1; + + for (int i = 0; i < _coreCount; i++) + { + if (_cpuId.Length > i && _cpuId[i].Length > 0) + { + CoreType coreType = _cpuId[i][0].CoreType; + + _coreNames[i] = coreType switch + { + CoreType.Performance => $"P-Core #{pCoreIndex++}", + CoreType.Efficient => $"E-Core #{eCoreIndex++}", + _ => CoreString(i) + }; + } + else + { + _coreNames[i] = CoreString(i); + } + } + int coreSensorId = 0; //core temp avg and max value @@ -350,23 +376,24 @@ internal sealed class IntelCpu : GenericCpu _coreTemperatures = new Sensor[_coreCount]; for (int i = 0; i < _coreTemperatures.Length; i++) { - _coreTemperatures[i] = new Sensor(CoreString(i), - coreSensorId, - SensorType.Temperature, - this, - new[] - { - new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]), - new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) - }, - settings); + _coreTemperatures[i] = new Sensor(_coreNames[i], + coreSensorId, + SensorType.Temperature, + this, + [ + new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]), + new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) + ], + settings); ActivateSensor(_coreTemperatures[i]); coreSensorId++; } } else - _coreTemperatures = Array.Empty(); + { + _coreTemperatures = []; + } // check if processor supports a digital thermal sensor at package level if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown) @@ -375,11 +402,10 @@ internal sealed class IntelCpu : GenericCpu coreSensorId, SensorType.Temperature, this, - new[] - { + [ new ParameterDescription("TjMax [°C]", "TjMax temperature of the package sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[0]), new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) - }, + ], settings); ActivateSensor(_packageTemperature); @@ -392,19 +418,21 @@ internal sealed class IntelCpu : GenericCpu _distToTjMaxTemperatures = new Sensor[_coreCount]; for (int i = 0; i < _distToTjMaxTemperatures.Length; i++) { - _distToTjMaxTemperatures[i] = new Sensor(CoreString(i) + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings); + _distToTjMaxTemperatures[i] = new Sensor(_coreNames[i] + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings); ActivateSensor(_distToTjMaxTemperatures[i]); coreSensorId++; } } else - _distToTjMaxTemperatures = Array.Empty(); + { + _distToTjMaxTemperatures = []; + } _busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); _coreClocks = new Sensor[_coreCount]; for (int i = 0; i < _coreClocks.Length; i++) { - _coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings); + _coreClocks[i] = new Sensor(_coreNames[i], i + 1, SensorType.Clock, this, settings); if (HasTimeStampCounter && _microArchitecture != MicroArchitecture.Unknown) ActivateSensor(_coreClocks[i]); } @@ -449,7 +477,7 @@ internal sealed class IntelCpu : GenericCpu if (EnergyUnitsMultiplier != 0) { - string[] powerSensorLabels = { "CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory", "CPU Platform" }; + string[] powerSensorLabels = ["CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory", "CPU Platform"]; for (int i = 0; i < _energyStatusMsrs.Length; i++) { @@ -482,7 +510,7 @@ internal sealed class IntelCpu : GenericCpu _coreVIDs = new Sensor[_coreCount]; for (int i = 0; i < _coreVIDs.Length; i++) { - _coreVIDs[i] = new Sensor(CoreString(i), i + 1, SensorType.Voltage, this, settings); + _coreVIDs[i] = new Sensor(_coreNames[i], i + 1, SensorType.Voltage, this, settings); ActivateSensor(_coreVIDs[i]); }