Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 121 additions & 1 deletion src/System/HardwareMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Reflection; // ★★★ 新增:用于反射关闭历史记录
using LibreHardwareMonitor.Hardware;
using LiteMonitor.src.Core;
using LiteMonitor.src.SystemServices; // ★★★ [MTT] 摩尔线程支持
using System.Linq;
using System.Threading;

Expand All @@ -15,6 +16,7 @@ public sealed class HardwareMonitor : IDisposable
#region Singleton & Events
public static HardwareMonitor? Instance { get; private set; }
public event Action? OnValuesUpdated;
public event Action? OnHardwareNamesCached; // ★★★ [新增] 硬件名称缓存完成事件 ★★★
#endregion

#region Private Fields
Expand All @@ -32,11 +34,15 @@ public sealed class HardwareMonitor : IDisposable

// 性能计数器管理器
private readonly PerformanceCounterManager _perfCounterManager;

// ★★★ [新增] 摩尔线程 GPU 监控器 ★★★
private readonly MttGpuMonitor _mttGpuMonitor;

private readonly Dictionary<string, float> _lastValidMap = new();

// 状态标记 (防止并发重载)
private volatile bool _isReloading = false;
private volatile bool _initialized = false; // ★★★ [新增] 标记硬件是否已初始化 ★★★

// 计时器相关
private long _tickCounter = 0;
Expand Down Expand Up @@ -86,6 +92,9 @@ public HardwareMonitor(Settings cfg)

// ★★★ [新增] 1. 初始化计数器管理器 (必须在 ValueProvider 之前) ★★★
_perfCounterManager = new PerformanceCounterManager();

// ★★★ [新增] 初始化摩尔线程 GPU 监控器 ★★★
_mttGpuMonitor = new MttGpuMonitor();

// 2. 初始化服务
_sensorMap = new SensorMap();
Expand All @@ -106,6 +115,9 @@ public HardwareMonitor(Settings cfg)
_lock,
_lastValidMap
);

// ★★★ [新增] 设置摩尔线程 GPU 监控器引用 ★★★
_valueProvider.SetMttGpuMonitor(_mttGpuMonitor);

// 3. 异步启动 (唯一优化:不卡UI)
InitializeAsync();
Expand All @@ -117,6 +129,99 @@ public HardwareMonitor(Settings cfg)
public float? Get(string key) => _valueProvider.GetValue(key);

public string GetNetworkIP() => _networkManager.GetCurrentIP();

// ★★★ [新增] 获取摩尔线程 GPU 数据 ★★★
public MttGpuData? GetMttGpuData() => _mttGpuMonitor?.Update();

// ★★★ [新增] 判断是否存在摩尔线程 GPU ★★★
public bool HasMttGpu => _mttGpuMonitor?.HasMttGpu ?? false;

// ★★★ [新增] 缓存 CPU/GPU 名称,避免重复获取 ★★★
private string _cachedCpuName = "";
private string _cachedGpuName = "";
private bool _namesCached = false;

/// <summary>
/// ★★★ [新增] 缓存硬件名称(在初始化完成后调用)★★★
/// </summary>
private void CacheHardwareNames()
{
try
{
// CPU
var cpu = _computer.Hardware.FirstOrDefault(h => h.HardwareType == HardwareType.Cpu);
_cachedCpuName = cpu?.Name ?? "";

// GPU
if (_mttGpuMonitor?.HasMttGpu == true && !string.IsNullOrEmpty(_mttGpuMonitor.GpuName))
{
_cachedGpuName = "Moore Threads " + _mttGpuMonitor.GpuName; // ★★★ 添加前缀 ★★★
}
else
{
var gpu = _sensorMap.CachedGpu;
_cachedGpuName = gpu?.Name ?? "";
}

_namesCached = true;

// ★★★ 触发事件,通知 UI 刷新 ★★★
OnHardwareNamesCached?.Invoke();
}
catch { }
}

/// <summary>
/// ★★★ [新增] 获取 CPU 名称 ★★★
/// </summary>
public string GetCpuName()
{
// 优先使用缓存
if (_namesCached && !string.IsNullOrEmpty(_cachedCpuName))
return _cachedCpuName;

try
{
var cpu = _computer.Hardware.FirstOrDefault(h => h.HardwareType == HardwareType.Cpu);
if (cpu != null && !string.IsNullOrEmpty(cpu.Name))
{
_cachedCpuName = cpu.Name;
return cpu.Name;
}
}
catch { }
return "";
}

/// <summary>
/// ★★★ [新增] 获取 GPU 名称 ★★★
/// </summary>
public string GetGpuName()
{
// 优先使用缓存
if (_namesCached && !string.IsNullOrEmpty(_cachedGpuName))
return _cachedGpuName;

try
{
// 优先:摩尔线程 GPU
if (_mttGpuMonitor?.HasMttGpu == true && !string.IsNullOrEmpty(_mttGpuMonitor.GpuName))
{
_cachedGpuName = "Moore Threads " + _mttGpuMonitor.GpuName; // ★★★ 添加前缀 ★★★
return _cachedGpuName;
}

// 其次:LHM 检测到的 GPU
var gpu = _sensorMap.CachedGpu;
if (gpu != null && !string.IsNullOrEmpty(gpu.Name))
{
_cachedGpuName = gpu.Name;
return gpu.Name;
}
}
catch { }
return "";
}

// ★★★ 新增:允许主程序手动触发驱动检查 (用于解决启动弹窗冲突) ★★★
public Task SmartCheckDriver() => _driverInstaller.SmartCheckDriver();
Expand Down Expand Up @@ -232,6 +337,12 @@ public void UpdateAll()

_valueProvider.OnUpdateTickStarted();

// ★★★ [新增] 更新摩尔线程 GPU 数据 ★★★
if (_mttGpuMonitor?.HasMttGpu == true)
{
_mttGpuMonitor.Update();
}

// 任务错峰执行 (调用 SystemOptimizer)
SystemOptimizer.RunMaintenanceTasks(_secondsCounter);

Expand Down Expand Up @@ -284,6 +395,7 @@ public void Dispose()
_valueProvider.Dispose();
_perfCounterManager.Dispose(); // ★★★ [新增] 释放计数器资源 ★★★
_fpsCounter.Dispose(); // <--- 新增
_mttGpuMonitor?.Dispose(); // ★★★ [新增] 释放摩尔线程 GPU 监控器 ★★★
_networkManager.ClearCache();
_diskManager.ClearCache(); // 漏掉的,补上
}
Expand All @@ -300,6 +412,9 @@ private void InitializeAsync()
// ★★★ [新增] 启动计数器预热 (不阻塞主 UI) ★★★
_perfCounterManager.InitializeAsync();

// ★★★ [新增] 初始化摩尔线程 GPU 监控器 ★★★
_mttGpuMonitor.Initialize();

// 这句耗时 4-5 秒,但在执行过程中,硬件会陆续添加到 _computer.Hardware
_computer.Open();

Expand All @@ -317,8 +432,13 @@ private void InitializeAsync()
// 2. 数据有了,再建立映射
_sensorMap.Rebuild(_computer, _cfg);

// ★★★ [新增] 3. 静态化预热:将所有传感器对象存入 Provider 缓存 ★★★
// 3. ★★★ [新增] 缓存硬件名称 ★★★
CacheHardwareNames();

// 4. 静态化预热:将所有传感器对象存入 Provider 缓存
_valueProvider.PreCacheAllSensors(_sensorMap);

_initialized = true; // ★★★ [新增] 标记初始化完成 ★★★
}

// 优化 T1:启动后大扫除
Expand Down
20 changes: 19 additions & 1 deletion src/System/HardwareServices/HardwareRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public static int GetHwPriority(IHardware hw)

// 1. 特殊处理:Microsoft Basic Render Driver 永远垫底
if (name.Contains("Basic Render", StringComparison.OrdinalIgnoreCase)) return 100;

// ★★★ [新增] 摩尔线程 GPU 优先级 (与 Nvidia/AMD 独显同级) ★★★
if (IsMttGpu(hw, name)) return 0;

// 2. Nvidia 显卡 (默认视为独显/最强)
if (hw.HardwareType == HardwareType.GpuNvidia) return 0;
Expand Down Expand Up @@ -62,6 +65,21 @@ public static int GetHwPriority(IHardware hw)
// 其他 -> 优先级 4
return 4;
}

/// <summary>
/// ★★★ [新增] 判断是否为摩尔线程 GPU ★★★
/// </summary>
public static bool IsMttGpu(IHardware hw, string? name = null)
{
name ??= hw.Name;
if (string.IsNullOrEmpty(name)) return false;

// 摩尔线程 GPU 名称特征:MTT, Moore Threads, 摩尔线程
return Has(name, "MTT") ||
Has(name, "Moore Threads") ||
Has(name, "摩尔线程") ||
Has(name, "MT ");
}

/// <summary>
/// 判断是否为独显版 Arc (A/B/Pro 系列)
Expand All @@ -83,7 +101,7 @@ public static bool IsDiscreteArc(string name)
public static bool ShouldUseSharedMemory(IHardware hw)
{
// 只有 Intel 核显才优先使用共享内存
// Intel 独显 (Arc A/B/Pro) 和其他厂商 (Nvidia/AMD) 都使用专用显存 (Dedicated)
// Intel 独显 (Arc A/B/Pro) 和其他厂商 (Nvidia/AMD/MTT) 都使用专用显存 (Dedicated)
if (hw.HardwareType == HardwareType.GpuIntel)
{
// 如果是 Discrete Arc,则不使用 Shared (即使用 Dedicated)
Expand Down
26 changes: 26 additions & 0 deletions src/System/HardwareServices/HardwareValueProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class HardwareValueProvider : IDisposable
// 子服务与处理器
private readonly PerformanceCounterManager _perfManager;
private readonly ComponentProcessor _componentProcessor;

// ★★★ [新增] 摩尔线程 GPU 监控器引用 ★★★
private MttGpuMonitor? _mttGpuMonitor;

// Tick 级智能缓存 (防止同帧重复计算)
private readonly Dictionary<string, float> _tickCache = new();
Expand Down Expand Up @@ -52,6 +55,14 @@ public HardwareValueProvider(Computer c, Settings s, SensorMap map, NetworkManag
// 初始化子服务
_componentProcessor = new ComponentProcessor(c, s, map);
}

/// <summary>
/// ★★★ [新增] 设置摩尔线程 GPU 监控器引用 ★★★
/// </summary>
public void SetMttGpuMonitor(MttGpuMonitor? monitor)
{
_mttGpuMonitor = monitor;
}

// ★★★ [新增] 清空缓存并重新预热(当硬件重载或配置变更时调用) ★★★
public void PreCacheAllSensors(SensorMap map)
Expand Down Expand Up @@ -459,6 +470,21 @@ public void OnUpdateTickStarted()
result = last;
}
}

// ★★★ [新增] 11. 摩尔线程 GPU 回退逻辑 ★★★
// 如果 LHM 未检测到 GPU 数据,尝试从摩尔线程 MTML 获取
if (result == null && _mttGpuMonitor?.HasMttGpu == true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Prefer MTML metrics when Moore Threads GPU is present

This condition only reads MTML data when result == null, so on systems where LibreHardwareMonitor still returns non-null GPU.* values for another adapter (for example an Intel iGPU), those values are kept even though the UI now uses Moore Threads naming via GetGpuName(). In that hybrid setup the panel can display a Moore Threads GPU label with telemetry from a different GPU, which corrupts reported GPU stats; MTML should be prioritized for GPU keys whenever HasMttGpu is true.

Useful? React with 👍 / 👎.

{
result = _mttGpuMonitor.GetValue(key);
if (result.HasValue)
{
// 记录最大值
if (key == "GPU.Clock" && result.Value > 0 && result.Value < 6000f)
_cfg.UpdateMaxRecord(key, result.Value);
else if (key == "GPU.Power" && result.Value > 0 && result.Value < 1200f)
_cfg.UpdateMaxRecord(key, result.Value);
}
}

// ★★★ [新增 4] 写入缓存并返回 ★★★
if (result.HasValue)
Expand Down
Loading