第2章:Jetson电源管理框架:Linux内核的CPUFreq与DevFreq子系统,Jetson特有的NV Power管理工具链
各位同学,咱们接着聊。上一章我讲了Jetson功耗的基本概念,这一章咱们深入底层,看看Jetson到底是怎么管电的。说白了,电源管理这件事,在Linux内核里就是两个核心子系统在干活:CPUFreq管CPU频率,DevFreq管其他设备频率。再加上NVIDIA自己搞的一套NV Power工具链,这三板斧就是Jetson电源管理的全部家当。
2.1 CPUFreq:CPU频率的“油门”
CPUFreq,全称是CPU Frequency Scaling。你想想看,CPU就像一辆车的发动机,跑得快就费油,跑得慢就省油。CPUFreq就是那个控制油门的脚。它根据系统负载,动态调整CPU的运行频率和电压。
我个人习惯,拿到一块Jetson板子,第一件事就是看看当前支持哪些governor(调控器)。governor就是CPUFreq的策略模式,常见的有这么几种:
- performance:一直跑最高频率,性能拉满,功耗也拉满。适合跑推理任务,不在乎电费。
- powersave:一直跑最低频率,省电第一。适合待机场景。
- ondemand:按需调节,负载高了就升频,低了就降频。这是很多Linux发行版的默认策略。
- conservative:比ondemand更保守,频率升降更平缓。适合对功耗波动敏感的场景。
- userspace:让用户自己写程序控制频率。适合做精细调优。
- schedutil:这是新内核里的调度器感知策略,能跟CFS调度器配合,反应更快。我个人比较推荐这个。
在Jetson上查看当前governor很简单:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
想切换governor,直接写进去就行:
echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2.2 DevFreq:不只是CPU,其他设备也要管
CPUFreq只管CPU,那GPU呢?内存控制器呢?总线呢?这些设备的频率谁来管?答案是DevFreq。
DevFreq是Device Frequency Scaling的缩写。它的设计思路跟CPUFreq很像,但适用范围更广。任何支持频率调节的设备,都可以通过DevFreq来管理。
在Jetson上,最重要的DevFreq设备就是GPU和EMC(External Memory Controller,外部内存控制器)。GPU跑游戏或推理时,频率高低直接影响帧率和功耗。EMC的频率则决定了内存带宽,对整体性能影响很大。
查看DevFreq设备列表:
ls /sys/class/devfreq/
你会看到类似这样的输出:
17000000.gpu 17000000.gpu/devfreq_dev emc
每个设备下面都有类似的属性文件,比如available_frequencies、cur_freq、governor等。操作方式跟CPUFreq几乎一样。
simple_ondemand、performance、powersave。但要注意,GPU的governor跟CPU的governor是独立的。你可以让CPU跑powersave省电,同时让GPU跑performance保证推理性能。这种“混合策略”在实际项目中很常见。
2.3 NV Power:NVIDIA的“独门秘籍”
好了,Linux内核的通用框架讲完了。但Jetson毕竟是NVIDIA的硬件,光靠通用框架还不够。NVIDIA自己开发了一套电源管理工具链,叫NV Power。这套工具链包括内核驱动、用户态工具和配置文件,专门针对Jetson平台做了优化。
NV Power的核心组件有:
- nvpmodel:电源模式管理工具。它定义了一组预设的功耗模式,比如10W模式、15W模式、MAXN模式等。每个模式对应一组CPU频率、GPU频率、内存频率和风扇策略。
- jetson_clocks:时钟频率管理工具。它可以手动锁定或解锁CPU、GPU、EMC的频率,方便做性能测试。
- tegrastats:实时功耗监控工具。它能显示CPU、GPU、内存、温度、电压等关键数据,是调试功耗问题的利器。
先说说nvpmodel。这个工具我用的最多。在Jetson Xavier NX上,默认有这些模式:
| 模式名称 | 功耗上限 | CPU核心数 | GPU频率 | 适用场景 |
|---|---|---|---|---|
| MAXN | 20W | 6 | 1100 MHz | 性能优先 |
| MODE_15W | 15W | 6 | 800 MHz | 平衡模式 |
| MODE_10W | 10W | 4 | 600 MHz | 省电模式 |
切换模式很简单:
sudo nvpmodel -m 1 # 切换到15W模式
查看当前模式:
nvpmodel -q
再说jetson_clocks。这个工具可以让你手动控制频率,不受nvpmodel的限制。比如你想测试GPU在最高频率下的功耗,可以这样:
sudo jetson_clocks --show # 查看当前所有频率
sudo jetson_clocks # 解锁所有频率到最大值
sudo jetson_clocks --restore # 恢复默认设置
最后是tegrastats。这个工具我几乎天天用。它每秒输出一行数据,包含CPU占用率、GPU占用率、内存带宽、温度、电压等。比如:
RAM 3985/7851MB (lfb 1905MB) CPU [0%@1400,0%@1400,0%@1400,0%@1400,0%@1400,0%@1400] EMC_FREQ 0% GR3D_FREQ 0% AO@36.5C CPU@37C GPU@36.5C PLL@36C Tboard@35C Tdiode@36.5C VDD_IN 4500/4500 VDD_CPU 1125/1125 VDD_GPU 1125/1125 VDD_SOC 1125/1125
这一行里,VDD_IN是输入功率(单位mW),VDD_CPU是CPU核心电压,GR3D_FREQ是GPU频率占用率。这些数据对分析功耗瓶颈非常有用。
2.4 实战:从零开始配置一个低功耗模式
好了,理论讲完了,咱们来点实战。假设你有一个电池供电的Jetson项目,要求续航4小时以上。你会怎么做?
我的思路是这样的:
- 先确定功耗预算:假设电池容量是60Wh,续航4小时,那平均功耗不能超过15W。留点余量,目标定在12W。
- 选择nvpmodel:从表格里看,10W模式最接近。但10W模式只开了4个CPU核心,GPU频率也低。如果应用对GPU要求不高,可以试试。
- 微调频率:用jetson_clocks把GPU频率锁定在600MHz,CPU频率锁定在1.2GHz。这样既能保证基本性能,又不会超功耗。
- 监控验证:用tegrastats跑30分钟,看平均功耗是否在12W以内。如果超了,再降一点频率。
- 固化配置:把nvpmodel和jetson_clocks的命令写进开机自启动脚本,这样每次开机自动进入低功耗模式。
嗯,这里要注意一点。Jetson的电源管理不是一锤子买卖。你调好的配置,换一个环境温度,或者换一个负载类型,可能就不适用了。所以一定要做充分的测试。
我曾经在一个户外项目中,白天温度35度,Jetson跑10W模式没问题。到了晚上温度降到10度,散热变好,功耗反而降了,性能却上不去。后来发现是nvpmodel的温控策略在低温下过于保守。最后我手动调整了温度阈值,才解决问题。
所以,电源管理这件事,没有银弹。你得理解底层原理,然后根据实际场景灵活调整。这一章的内容,就是帮你打好这个基础。
下一章,咱们聊聊Jetson的硬件功耗测量方法,包括怎么用INA3221电流传感器,怎么用外接万用表做精确测量。到时候我会分享一些我在实验室里踩过的坑,保证让你少走弯路。