C++获取Mellanox网卡及CPU温度方案问询(Windows11环境)
解决方案:Windows 11下C++获取Mellanox网卡及CPU温度
一、Mellanox ConnectX-5网卡温度获取(无命令行调用)
方法1:通过Mellanox WinOF-2 WMI接口查询
Mellanox WinOF-2驱动自带WMI类,可直接通过C++的WMI客户端查询温度数据,无需额外依赖:
- 引入依赖头文件与库:
#include <windows.h> #include <wbemidl.h> #include <comdef.h> #pragma comment(lib, "wbemuuid.lib")
- 核心查询实现:
HRESULT GetMellanoxNicTemp(double& temp) { HRESULT hres; // 初始化COM环境 hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) return hres; hres = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hres)) { CoUninitialize(); return hres; } // 创建WbemLocator实例 IWbemLocator* pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc ); if (FAILED(hres)) { CoUninitialize(); return hres; } // 连接Mellanox WMI命名空间 IWbemServices* pSvc = NULL; hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\Mellanox"), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); return hres; } // 设置代理权限 hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return hres; } // 查询温度数据 IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM MLNX_NIC_Temperature"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return hres; } IWbemClassObject* pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) break; VARIANT vtProp; hr = pclsObj->Get(L"CurrentTemperature", 0, &vtProp, 0, 0); temp = vtProp.dblVal; // 直接获取摄氏度数值 VariantClear(&vtProp); pclsObj->Release(); break; } // 释放资源 pEnumerator->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return WBEM_S_NO_ERROR; }
方法2:使用Mellanox ConnectX SDK直接调用
Mellanox官方提供Windows版ConnectX SDK,可直接调用硬件级API读取传感器数据:
- 下载并安装Mellanox ConnectX SDK for Windows
- 引入SDK依赖:
#include <mlx5/sensors.h> #pragma comment(lib, "mlx5.lib")
- 读取温度实现:
int GetMellanoxNicTempViaSDK(double& temp) { mlx5_context* ctx = mlx5_open_device(0); // 0对应第一个网卡,多网卡需遍历设备ID if (!ctx) return -1; mlx5_sensor_data data; if (mlx5_get_sensor(ctx, MLX5_SENSOR_TEMPERATURE, &data) != 0) { mlx5_close_device(ctx); return -1; } temp = data.value / 1000.0; // 原始值为毫摄氏度,转换为摄氏度 mlx5_close_device(ctx); return 0; }
二、CPU温度获取(适配AMD/Intel)
通用方法:WMI跨厂商查询
WMI可同时适配AMD Threadripper 3960X与Intel 11代Core i7,无需额外SDK:
#include <windows.h> #include <wbemidl.h> #include <comdef.h> #pragma comment(lib, "wbemuuid.lib") HRESULT GetCpuTemp(double& temp) { HRESULT hres; CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) return hres; CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hres)) { CoUninitialize(); return hres; } IWbemLocator* pLoc = NULL; CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc ); if (FAILED(hres)) { CoUninitialize(); return hres; } IWbemServices* pSvc = NULL; pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); return hres; } CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return hres; } // 查询CPU热区温度 IEnumWbemClassObject* pEnumerator = NULL; pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return hres; } IWbemClassObject* pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) break; VARIANT vtProp; hr = pclsObj->Get(L"Temperature", 0, &vtProp, 0, 0); // 原始值为1/10开尔文,转换为摄氏度 temp = (vtProp.uintVal - 2732) / 10.0; VariantClear(&vtProp); pclsObj->Release(); break; } pEnumerator->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return WBEM_S_NO_ERROR; }
厂商专属精准方案
- AMD Threadripper 3960X:使用AMD Ryzen Master SDK,可获取单核心级温度数据,需下载官方SDK并链接
RyzenMasterSDK.lib - Intel 11代Core i7:使用Intel Power Gadget SDK,通过
IntelPowerGadget.h中的GetTemperature接口获取精准核心温度,需安装Intel Power Gadget并引用SDK
注意事项
- 程序需以管理员权限运行,否则WMI或SDK无法访问硬件传感器
- 确保Mellanox WinOF-2驱动为最新版本,避免API兼容性问题
- 高负载测试时,建议同时监控网卡RX/TX队列使用率、PCIe带宽,排除非温度因素导致的性能下降
内容的提问来源于stack exchange,提问作者Valdez
相关产品推荐
相关产品推荐

