sgminer ADL集成揭秘:如何读取GPU温度、风扇并实现超频的完整实现原理
【免费下载链接】sgminerScrypt GPU miner项目地址: https://gitcode.com/gh_mirrors/sg/sgminer
sgminer 是一款著名的开源 GPU 挖矿客户端,而它的ADL(AMD Advanced Data Link)集成正是读取 GPU 温度、风扇转速并实现超频调频的核心能力。这篇文章带你完整拆解 sgminer ADL 模块的实现原理:从动态加载驱动库、枚举显卡、温度/频率读取,到风扇控制与智能温控超频算法,新手也能看懂。
📌 什么是 ADL?sgminer 与 AMD 显卡之间的"桥梁"
ADL 是 AMD 官方提供的显卡硬件监控与控制接口。sgminer 并没有把 ADL 编译进程序,而是运行时动态加载驱动库:
| 平台 | 加载方式 | 对应库文件 |
|---|---|---|
| Linux | dlopen()动态加载 | libatiadlxx.so |
| Windows | LoadLibrary() | atiadlxx.dll(失败则回退 32 位的atiadlxy.dll) |
这种"运行时加载 + 函数指针"的设计有两大好处:
- 不强依赖驱动:没有 AMD 显卡的机器也能正常编译运行,程序里所有 ADL 功能自动降级为空操作(见 adl.h 中
#else分支的 inline 空函数); - 跨平台统一:Linux 下用
dlsym、Windows 下用GetProcAddress,代码里统一封装成GetProcAddress(adl.c)。
相关的核心文件一目了然:
- adl.c — 全部实现(约 1800 行):初始化、读数、超频、温控
- adl.h — 对外接口:
gpu_temp()、gpu_fanspeed()、gpu_autotune()等 - adl_functions.h — ADL 3.0 全部函数指针类型定义(Overdrive 5/6)
- ADL_SDK/readme.txt — 官方 SDK 说明
🚀 初始化四步走:搭好硬件监控系统
程序启动时由 driver-opencl.c 调用init_adl(),内部流程如下:
第 1 步:加载库并解析函数
prepare_adl()(adl.c)打开驱动库后,逐个解析约 30 个 ADL 函数指针,然后调用ADL_Main_Control_Create()初始化、ADL_Main_Control_Refresh()刷新设备列表,再依次探测 Overdrive 5/6 API 是否可用。
第 2 步:枚举系统中的所有适配器
通过ADL_Adapter_NumberOfAdapters_Get()+ADL_Adapter_AdapterInfo_Get()拿到每张卡的索引、PCI 总线号、BIOS 信息。其中ADL_Adapter_ID_Get()返回0 就表示不是 AMD 卡,会被跳过——这就是 sgminer 只监控 AMD 显卡的原因。
第 3 步:OpenCL 设备与 ADL 设备"对号入座"
这是多卡用户最常踩的坑:OpenCL 和 ADL 各自独立枚举显卡,两者顺序可能不一致。sgminer 的策略是:
- 默认假设两者顺序一致;
- 数量对不上时会明确报错,提示使用
--gpu-map手动映射(adl.c); - Windows 下总线号顺序混乱,可用
--reorder按总线号重新排序(adl.c)。
第 4 步:记录默认值并应用用户超频参数
程序会保存每张卡的出厂性能档位(DefPerfLev)和风扇默认值,以便退出时一键还原;随后应用--gpu-engine、--gpu-memclock、--gpu-vddc、--gpu-fan、--gpu-powertune等启动参数(adl.c)。
💡 还有一个贴心细节:双芯显卡(如某些双 GPU 矿卡)上只有一颗 GPU 带风扇控制接口。sgminer 通过"总线号相差 1 + 同名显卡"自动识别出孪生 GPU(twin),让没有风扇接口的那颗共享孪生兄弟的风扇数据(adl.c)。
🌡️ 温度、频率、风扇:底层都是哪几个 ADL 调用?
所有读数函数都遵循同一模式:加互斥锁 → 调 ADL 接口 → 换算单位 → 解锁。核心换算关系值得记住:
| 监控项 | ADL 接口 | 单位换算 |
|---|---|---|
| GPU 温度 | ADL_Overdrive5_Temperature_Get | 原始值 ÷ 1000 = ℃ |
| 核心频率 / 显存频率 / 电压 / 活动率 | ADL_Overdrive5_CurrentActivity_Get | 频率 ÷ 100 = MHz,电压 ÷ 1000 = V |
| 风扇转速(RPM) | ADL_Overdrive5_FanSpeed_Get | 设为SPEED_TYPE_RPM模式 |
| 风扇百分比 | 同上 | 设为SPEED_TYPE_PERCENT模式 |
| 功耗调节 | ADL_Overdrive5_PowerControl_Get | 百分比(-20 ~ +20) |
对应实现分别在 gpu_temp()、gpu_engineclock()、gpu_fanspeed()。
两个值得学习的工程设计:
- 一次性全量读取:
gpu_stats()(adl.c)在一把锁内批量读出温度、双频、电压、风扇、功耗,避免多把锁交叉带来的性能损耗; - 驱动故障自愈:若显卡突然停止上报风扇转速(驱动崩溃的典型症状),
gpu_fanpercent()会自动禁用该卡的监控并触发app_restart()重启保护(adl.c)。
⚡ 超频原理:性能档位的"读—改—写—回读"
AMD 显卡的频率/电压保存在**性能档位表(ODPerformanceLevels)**中,通常有多个档位(空闲/中/最高)。sgminer 的超频函数set_engineclock()、set_memoryclock()、set_vddc()共用同一套套路(adl.c):
- 读:取出当前全部档位(
ODPerformanceLevels_Get); - 改:修改最高档的目标值,并把所有低于目标值的低档位一并钳制到该值——因为"低档位不能比高档位还高";
- 写:
ODPerformanceLevels_Set()写回驱动; - 回读校验:再次 Get 确认驱动真的接受了新值,并更新内部缓存的 min/max 边界。
单位小约定:频率以MHz×100(0.01 MHz 精度)传输,电压以mV(×1000)传输。
风扇控制(set_fanspeed())多两个关键步骤:
- 先置位
USER_DEFINED_SPEED标志,把风扇从"驱动自动"切换到"用户手动"; - 老显卡只支持写 RPM 不支持写百分比时,自动换算:
RPM = 最大RPM × 百分比 ÷ 100。
🎯 智能温控:超频与散热之间的自动闭环
sgminer 最精彩的部分是gpu_autotune()(adl.c),它把"超频"变成了负反馈闭环——温度是目标,风扇和频率是手段。三个默认阈值:
目标温度 targettemp = 75℃ | 过热温度 overheat = 85℃ | 迟滞 hysteresis = 3℃风扇自动调节(fan_autotune,adl.c):
- 温度 > 过热温度 → 风扇直接拉满 100%并报告过热错误;
- 温度 > 目标温度 → 按迟滞判断,风扇 +5% 或 +10%;
- 温度 < 目标温度 − 迟滞值 → 风扇按比例缓慢下降,防止"抖动"。
核心频率自动调节:
- 超过cutoff 温度→ 降频到最低并停用该卡(
DEV_RECOVER),等温度回落自动恢复(adl.c); - 超过过热温度 → 直接降频到最低速;
- 温度略高于目标 → 按驱动报告的步进值(
iStep)逐级降频; - 温度低于目标 →逐级提频,温差大时步进翻倍加速爬升。
⚠️ 迟滞(hysteresis)是经典控制思想:温度必须偏离目标 3℃ 以上才动作,避免风扇/频率在临界点来回振荡。
🛠️ 上手实践:常用参数与交互面板
启动时即可让 ADL 干活(参数定义见 sgminer.c):
sgminer --gpu-engine 850 --gpu-fan 80 --autofan --autoengine| 参数 | 作用 |
|---|---|
--gpu-engine <MHz> | 启动时设定核心频率 |
--gpu-memclock <MHz>/--gpu-memdiff | 设定显存频率(或相对核心的偏移) |
--gpu-vddc <V> | 设定核心电压 |
--gpu-fan %/--gpu-minfan % | 风扇上限/下限(自动风扇模式) |
--gpu-powertune % | 功耗调节(-20 ~ +20) |
--gpu-map n,m | 手动映射 OpenCL 卡序 → ADL 卡序 |
--autofan/--autoengine | 开启风扇 / 频率自动温控 |
终端交互模式下按c进入设置面板,可实时查看Temp / Fan Speed / Engine Clock / Vddc,并按单字母操作(adl.c):
- E核心频率 ·F风扇 ·M显存频率 ·V电压 ·P功耗 ·A自动参数
- U Ultratune:自动扫描核心 × 显存频率组合(GPU 按 10MHz、显存按 5MHz 步进),实测每种组合的哈希率,最后自动应用收益最高的那组频率——一个基于 ADL 的"自动化暴力调优器"(adl.c)。
🛡️ 安全设计:退出即还原,风险可控
- 自动还原:正常退出/重启时
clear_adl()只对被修改过的卡(managed标志)恢复出厂性能档位和默认风扇,再销毁控制、卸载驱动库(adl.c); - 边界保护:所有手动设置都校验安全范围,越界会要求二次确认;
- 官方警告:
adl_functions.h头部明确写着——同时拉高电压/频率却调低风扇,可能烧毁显卡(adl_functions.h)。
📚 延伸阅读
- 整体架构文档:doc/MINING.md、doc/FAQ.md
- 多算法支持入口:algorithm/ 目录(scrypt、sha2 等)
- OpenCL 驱动层与 ADL 的衔接:driver-opencl.c
- 设备结构体
struct gpu_adl定义:miner.h
一句话总结:sgminer 用"运行时动态加载 + 函数指针"解耦 AMD 驱动,用"锁内批量读取"保证监控线程安全,用"目标温度 + 迟滞 + 步进"的负反馈算法让超频与散热自动平衡——这套 ADL 集成的实现思路,至今仍值得所有硬件监控类项目借鉴。
【免费下载链接】sgminerScrypt GPU miner项目地址: https://gitcode.com/gh_mirrors/sg/sgminer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考