新显卡拿到手装完Ubuntu 22.04后的第一件事我从来不是跑分而是烤机。跑分软件跑出个漂亮成绩不代表这块卡在持续满载下不会掉驱动3DMark那种几十秒的负载更是看不出散热和供电的真实水平。去年我在验收一批新卡时试过不少工具最后固定下来用gpu_burn做主力压测。它不渲染画面、不依赖窗口直接通过CUDA把GPU的浮点单元和显存控制器按到峰值状态方向清晰、反馈直观非常适合判断一块显卡在持续重负载下的稳定性。这篇就详细聊聊我在Ubuntu 22.04上从零安装、编译、运行gpu_burn的完整过程包括踩过的坑和可以直接抄走的命令。1. 为什么选gpu_burn烤机工具选型与负载原理1.1 烤机到底在测什么很多人理解烤机就是“让显卡跑得很热”其实不完全对。显卡稳定性测试主要暴露三个层面散热系统能否把核心、显存、供电模块的热量及时带走供电方案在长期高功耗下有无波动或不足驱动和硬件在持续满载下是否会崩溃、掉驱动、重启。这三个问题靠短时间跑分根本看不出来必须让GPU稳定运行在接近TDP热设计功耗的状态并且持续足够长时间。我之前也试过在Linux下用FurMark一类工具虽然能拉高负载但界面依赖X Window服务器上没显示器就麻烦。还有各种benchmark负载是脉冲式的待机的低载和满载交替出现温度曲线一直在毛刺反而不容易判断平台期。真正干这行的人最终都会回到纯计算内核的压测工具。1.2 常见烤机工具对比工具负载类型界面依赖主要考察点适合场景gpu_burnCUDA计算持续满载无散热、供电、驱动稳定性长期压测、无头服务器FurMarkOpenGL渲染满载需要X Window图形渲染稳定性、显存有桌面环境的显卡测试3DMark类短时混合负载需要性能表现性能对比不适合稳定性显存专项工具访存压力为主无显存颗粒好坏二手卡/矿卡筛查选定gpu_burn的核心原因很简单定向、可控、无窗口依赖。它能精准把SM流处理器簇顶到接近100%占用功耗直接推到TDP让所有潜在问题在稳定负载下现形。1.3 gpu_burn的负载原理理解gpu_burn的工作方式对你日后解读测试结果很有帮助。它的实现思路来自图像重建领域经典的CUDA计算内核程序在显存里分配若干浮点数组然后反复执行矩阵乘加运算。这个计算模式有两个特点一是算术逻辑单元几乎每周期都在干活二是共享存储器和寄存器也被持续访问。所以它压的不只是核心频率还把显存控制器、L2缓存、供电回路全部拉进高负载状态。用跑步机来类比你想测一个人的心肺极限就该让他持续在跑步机上匀速跑而不是让他一会儿冲刺一会儿休息。gpu_burn就是这台“匀速满速”的跑步机跑完后观察的心率、体温、出汗量对应到显卡上就是温度、功耗、核心频率这三个核心指标。2. Ubuntu 22.04下的环境准备驱动、CUDA与编译链2.1 先确认驱动和CUDA到底装没装很多人在这一步栽跟头。装完Ubuntu 22.04后如果通过“软件与更新”的附加驱动页面安装了NVIDIA驱动那么nvidia-smi命令正常能输出显卡型号和驱动版本但顶部的“CUDA Version”只是驱动支持的最大运行时版本并不代表系统已经装好CUDA Toolkit。如果你接着输入nvcc --version却提示找不到命令说明缺的是编译工具链不是驱动。gpu_burn编译直接依赖nvcc和cuda_runtime.h所以必须装CUDA Toolkit。我见过有人明明跑得起gpu_burn的二进制但因为没装开发版工具链无法自行编译最后被迫去找别人的静态编译版本很被动。检查命令很简单nvidia-smi nvcc --versionnvidia-smi正常只能证明卡能被驱动识别nvcc存在才代表CUDA编译环境可用。2.2 CUDA Toolkit安装apt是最省心的路径在Ubuntu 22.04下我推荐先走apt仓库安装除非你需要特定CUDA版本否则不用去官网折腾runfile安装器。sudo apt update sudo apt install nvidia-cuda-toolkit这套装完nvcc、CUDA头文件、libcudart运行时库都会就位。gpu_burn对CUDA版本要求很宽松我在CUDA 12.0、12.4的工具链上都编译过均能正常通过。所以没必要追求最新版本稳定能用的就好。需要注意如果你用官网的runfile方式安装要确保安装的是完整Toolkit而不是只装了驱动。另外runfile默认把CUDA装在/usr/local/cuda让它保持默认路径能省掉后面很多麻烦。2.3 编译链与头文件路径验证接着安装通用编译工具sudo apt install build-essential这一条会把gcc、g、make等一整套基础工具补齐。虽然主要编译器是nvcc但CUDA编译过程中会调用宿主的gcc来处理某些步骤没有gcc会直接报错。Ubuntu 22.04默认的gcc 11对常见CUDA版本兼容性没问题不用自己换gcc版本。保险起见验证头文件路径find /usr -name cuda_runtime.h 2/dev/null正常会在/usr/include或/usr/local/cuda/include等位置找到。如果啥都没找到说明CUDA Toolkit没装完整回头检查上一步如果找到了环境就算备齐了。3. 获取源码、修正Makefile与一次性编译3.1 拉取源码和目录结构代码量非常小把仓库clone下来即可git clone https://github.com/wilicc/gpu-burn cd gpu-burn ls -l目录里核心文件就几个gpu_burn.cu主程序负责分配显存、调用内核、循环计时、输出状态compare.cu和gpu_burn_common.h计算实现与结果校验Makefile编译入口。这种小项目的Makefile通常只做一件事调用nvcc把.cu源文件编译成目标文件再链接libcudart生成可执行文件。没有复杂的依赖关系编译链路能拉通就等于成功。3.2 Makefile里需要动的地方打开Makefile最先看到的两行核心配置CUDA_PATH ? /usr/local/cuda NVCCOPT ? -O2 -Wno-deprecated-gpu-targetsCUDA_PATH指定CUDA Toolkit的根目录编译时会用它拼接include和lib路径。大多数Ubuntu系统在/usr/local/cuda有软链接直接指向实际安装的版本目录所以默认值一般够用。真正要留意的编译命令是这样的等价转换nvcc -O2 -Wno-deprecated-gpu-targets -c gpu_burn.cu -o gpu_burn.o nvcc -O2 gpu_burn.o -o gpu_burn -L$(CUDA_PATH)/lib64 -lcudart关键点是链接的是libcudartCUDA运行时库不是libcuda驱动API库。这决定了它必须在装有CUDA Toolkit的环境下编译而不是光有驱动就能搞定。如果CUDA被装在自定义路径比如某些人喜欢放/opt/cuda就修改第一行CUDA_PATH ? /opt/cuda改完重新make即可。3.3 编译报错的三个常见场景第一类报错cuda_runtime.h: No such file or directory。这个最直接要么CUDA Toolkit没装要么CUDA_PATH指定的目录下没有include文件夹。处理办法确认/usr/local/cuda软链接指向的版本目录存在完整头文件如果机器上装了多个CUDA版本建议直接指定具体版本路径比如CUDA_PATH/usr/local/cuda-12.4避免软链接指到一个残缺目录。第二类gcc: error: unrecognized command line option -stdc14这类宿主编译参数问题。Ubuntu 22.04默认gcc 11一般不会触发但如果你的PATH环境变量被改过nvcc调用了gcc 9或更低版本就会出这问题。解决办法是确认当前生效的gcc版本恢复默认环境。第三类链接阶段报cannot find -lcudart。说明libcudart.so不在-L指定的搜索路径里或者被装到了别的lib目录。先确认文件存在ls /usr/local/cuda/lib64/libcudart.*确认后再修改Makefile中的CUDA_PATH必要的话执行sudo ldconfig刷新库缓存。还有一类警告编译时老是输出nvcc warning: The -stdc11 flag is not supported之类。这是老项目适配新编译器的提示完全不影响产物忽略就好不用强迫症发作去改Makefile。3.4 编译成功后的产物验证执行编译make clean make看到一连串nvcc输出后停住终端回到提示符没有红色error就说明编译成功。生成的可执行文件名为gpu_burn确认一下属性和依赖ls -lh gpu_burn ldd gpu_burn | grep cudartldd输出里能看到libcudart.so.12类字样说明链接关系正确。此时可以先跑个10秒自测./gpu_burn 10如果能正常输出表格并结束编译环节就算彻底通关。4. 烤机参数、输出表格与通过标准4.1 命令行参数出奇简单gpu_burn的用法就是一行./gpu_burn [时间秒数]比如烤5分钟./gpu_burn 300它只接受一个正整数参数表示运行时长。不带参数的部分版本会无限跑下去直到你CtrlC。我建议任何时候都显式带秒数不仅便于脚本管理也能让你明确知道边界不用开着计时器盯屏幕。长时间压测不想让SSH会话一直占用就用后台方式运行nohup ./gpu_burn 3600 burn.log 21 断开SSH后测试继续跑回来看日志就行。4.2 输出表格里每一列的含义正常运行时终端每秒刷新一行状态大致包含这样几列信息GPU编号从0开始的序号对应nvidia-smi里的GPU索引温度GPU核心当前温度通常几十秒后到达平台期功耗整卡功耗会贴近TDP标称值SM频率核心实时频率烤机时通常处于boost频率附近显存频率显存控制器频率SMs占用情况流处理器簇的利用率。解读的关键是趋势而不是单点值。温度如果在几秒内冲到90°C以上并继续缓慢上涨说明散热余量不足如果功耗一直低于标称TDP的70%可能存在供电限制或电源管理模式问题。频率方面只要全程能维持boost值不剧烈掉频就是合格表现。4.3 多卡环境下如何确认每张卡都在满载多卡机器上运行gpu_burn会自动枚举所有支持CUDA的GPU每张卡各起一个线程。想要确认每张卡的负载状态另开终端用watch刷新watch -n 1 nvidia-smi重点看Volatile GPU-Util是否为100%以及各卡的温度、功耗是否同步波动。正常情况下每张卡的功耗都该接近自己的TDP如果某张卡功耗明显偏低要怀疑它的供电线或者PCIe插槽接触或者该卡正被其他进程占用。gpu_burn有一种情况非常容易让人误判它在启动时会等待当前没有其他CUDA上下文占用目标GPU。如果某张卡正被其他进程占用输出会停在“Waiting for all processes on Cuda X to finish!”看起来像卡住其实就是上下文冲突。尤其是接了显示器的机器Xorg默认占用GPU 0导致它永远等下去。解决思路在后面排查章节详说。4.4 什么样的结果才算通过我自己用的通过标准有三条拧成一股绳设定时长完整跑完进程退出码为0全程没有任何显存错误、驱动重启或NVRM Xid报错温度曲线进入平台期后不再持续爬升功耗贴近TDP。这三个条件同时满足这块卡就算通过了满载稳定性测试。如果只是跑完没报错但温度从85°C一路爬到100°C那也不算合格只是时间还没到暴露问题的时候。5. 实测踩过的坑从掉线到Xorg占用的完整排查5.1 坑一长时烤机时显卡掉线现象很典型烤了20多分钟SSH连接正常但输出日志从某一行开始不再更新接着执行nvidia-smi直接报错显示GPU Lost。第一次遇到我是从电源入手的那块卡只有一条8pin供电线插着另一个供电口空着高负载下电压跌落驱动直接判定GPU失联。排查链路我总结成固定的三步dmesg -T | grep -i nvrm看有没有Xid报错。如果有PCIe链路错误或GPU Bus Error字样优先怀疑供电和PCIe插槽如果整机直接断电重启那大概率是供电过流保护触发。解决方式很直白换额定功率足够的电源把每个供电口都插满PCIe卡插到靠近CPU的第一条x16插槽再重跑同样时长的测试。烤机暴露出的这种问题在实际生产环境里早晚会变成服务宕机越早暴露越好。5.2 坑二编译告警和真正致命的报错怎么区分编译时经常出现一类警告比如nvcc warning: The -stdc11 flag is not supported这类来自老源代码适配新编译器的提示不会影响生成产物放心忽略。但下面这种千万别忽略unsupported gpu architecture compute_XX这表示nvcc不认识编译目标里指定的GPU架构字符串。多发生在旧版本CUDA工具链配新显卡或者Makefile里写死了某个架构参数。解决办法是去掉或更新Makefile中的-gencode archcompute_XX选项改成当前卡对应的架构。在Ubuntu 22.04默认的CUDA工具链上这个报错很少出现但如果你用的CUDA版本很老就会遇到。还有一种隐蔽情况系统里同时有gcc 9和gcc 11PATH环境变量指向了旧版本nvcc调用老gcc处理宿主代码时崩溃出一堆模板报错。排查时先看which gcc gcc --version恢复系统默认gcc版本后问题一般烟消云散。5.3 坑三Xorg占用GPU导致无法烤机接显示器的机器默认图形界面会占用编号最小的GPU导致gpu_burn在这块卡上无限等待。这个问题我第一次遇到时以为程序挂了还专门重编了一次。判断方法很简单nvidia-smi输出里如果看到Xorg或者gnome-shell进程占着某个GPU而gpu_burn的输出恰好停在“Waiting for all processes on Cuda 0 to finish!”那基本就是这个原因。最快的处理方式是切到纯命令行模式sudo systemctl isolate multi-user.target烤完再切回图形界面sudo systemctl isolate graphical.target或者干脆拔掉显示器用SSH操作。无头服务器没这个问题但大部分个人测试机第一步就得这么处理。5.4 坑四核心温度正常显存温度却爆了gpu_burn虽然以计算为主但显存控制器持续高频访问显存发热量非常可观。有些显卡的显存散热被核心散热器遮挡或者散热垫老化就会出现核心温度还算正常、显存温度却已经超标的“隐形问题”。想看显存温度需要用nvidia-smi -q -d TEMPERATURE重点关注Memory Junction Temperature。在室温25°C左右的环境下绝大多数显卡烤机时显存温度应该控制在95°C以内超过105°C就属于危险区。显存长期过热会加速颗粒老化甚至出现花屏。这种问题是跑分软件永远测不出来的只有长时长满载烤机能帮你提前发现。5.5 额外观察功耗被限制和风扇策略还有一个容易被忽略的现象有些卡烤机时功耗始终上不去比如标称170W的卡只有120W。这不一定代表显卡坏了先检查电源管理模式nvidia-smi -q -d POWER如果显示Enforced Power Limit被设得很低可能是上次测试遗留的设置或者驱动默认的功耗管理策略太保守。功耗上不去还和风扇策略相关部分卡默认不开启主动散热曲线导致核心温度一高就降频表现为功耗和频率都会周期性波动。这时候可以在nvidia-smi里临时调整风扇策略来辅助散热但注意不是所有卡都支持风扇转速控制。6. 进阶把烤机做成自动化验收流程6.1 配合nvidia-smi dmon采样gpu_burn自带的输出虽然能作参考但要分析完整曲线还是要靠nvidia-smi dmon单独记录。一条实用命令nvidia-smi dmon -s pucvmet -d 5 -c 720 dmon.log 其中-s pucvmet指定采集项分别代表功耗、利用率、时钟、显存、温度、事件-d 5表示每5秒采样一次-c 720表示采样720次总共能覆盖1个小时。测试结束后用awk或Excel打开dmon.log就能还原出完整的温度、功耗曲线。6.2 一套可以直接复制的验收脚本我每次验收新卡或排查旧卡都会跑同一个脚本把gpu_burn和dmon串起来结束后自动检查关键字。逻辑很简单#!/bin/bash DURATION${1:-600} LOG_DIR$(date %Y%m%d_%H%M%S)_burn mkdir -p $LOG_DIR echo 开始烤机 $DURATION 秒 ./gpu_burn $DURATION | tee $LOG_DIR/gpu_burn.log BURN_PID$! nvidia-smi dmon -s pucvmet -d 5 -c $((DURATION / 5)) $LOG_DIR/dmon.log MON_PID$! wait $BURN_PID BURN_RC$? kill $MON_PID 2/dev/null echo 烤机退出码: $BURN_RC grep -iE error|fail|xid $LOG_DIR/*.log || echo 日志中未发现错误关键字脚本会生成带时间戳的目录把gpu_burn日志和dmon采样归档到一起。以后想追溯某台机器的散热历史翻文件夹就行。6.3 多轮测试节奏建议新卡到手不要直接跑60分钟的长测。我的习惯是分三步走先跑60秒确认驱动加载、温度、功耗数据都正常再跑15分钟观察温度是否进入平台期功耗是否稳定贴近TDP最后跑30分钟到60分钟验证整机供电和散热系统的长期稳定。如果在第1步就出现温度异常或者进程崩溃后面长测没必要继续直接排查散热、电源和驱动版本问题。这套节奏既节省时间又能快速定位异常卡。我在帮同事做装机验收时就是靠这个节奏把一批电源有问题的卡筛出来的。最后分享一点长期经验。gpu_burn不是跑分软件它不告诉你显卡有多快只负责把负载拉满让你有机会发现散热、供电和驱动层面的隐患。所以我每次做完测试都会把日志按日期归档新卡装好时留一个基线。用上几个月后再烤一次同室温下对比温度曲线如果发现温度明显变高那通常意味着散热老化或者硅脂干了该维护了。这个习惯从装机验收一路延续到日常运维帮我提前处理了不少隐患。