3 种软件方法获取 Android 设备的功耗
硬件方法获取功耗虽然准确,但需要功耗版/power monitor,成本较高,且不方便。Android 系统中也有软件测功耗的方法,下面分别介绍 BatteryManager
类, adb
和 Perfetto
方法。
BatteryManager 类
适用于应用上层,在 SDK 21 及以上可用。
1 | BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE); |
Adb 方法
1 | shell:/ $ find -name current_now 2>/dev/null # adb shell 中输入 |
Perfetto 测器件功耗
瞬时功耗波动很大,以上两个接口获取的数据很可能并不准确。使用 Perfetto 可以监控并获取一段时间的功耗。
Wattson 测 CPU 每个核心的功耗
CPU 性能功耗相关数据获取
Capacity:
1 | cat /sys/devices/system/cpu/cpu*/cpu_capacity |
获得最高频的capacity,其他频率的可以直接折算。
Power:
芯片的dtsi中会有,可以直接在内核中dts
文件夹进行寻找
https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/
如果没有找到,可以重新编译内核,在energy_model初始化时加一句printk打印出来。
1 | diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c |
就可以打印出这样的信息:
1 | cpu cpu0: #0: freq:300000 power:10 |
capacity/power,就可以得到能效比(energy efficiency ratio,EER)
如骁龙 8+gen1 sm8475 的EER表:
使用Wattons插件
有了频点对应的power表后,可以使用perfetto的wattson插件预估功耗,这个工具会基于每个核频点和运行时间计算功耗。使用前,需要把energy_model中的 power 数据导入到perfetto的 sql 中。
先将perfetto源码clone下来
1 | git clone https://android.googlesource.com/platform/external/perfetto/ |
然后将刚刚的power数据加到src/trace_processor/perfetto_sql/stdlib/wattson/curves/device.sql 中的_device_curves_1d表中,由于我们只知道运行时功耗,将 static, idle0, idle1 功耗都填0,active功耗填em的power。
在src/trace_processor/perfetto_sql/stdlib/wattson/device_info.sql 中
- _wattson_device_map表中将CPU和手机的型号对应,手机型号应该在 adb shell 时会打印在 shell 输入的左边,如k60是mondrian。
- 在 _device_cpu_deep_idle_offsets 表写每个核心的idle时间,每个核心直接写0
- 在_cpu_to_policy_map 表写每个 cpu 核对应的调频policy
- 在 _device_min_volt_vote 表中填小核最低频点
如 sm8475 的数据:
1 | diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/curves/device.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/curves/device.sql |
保存后编译perfetto:
1 | # Install build dependencies |
服务器会在 localhost:10000 中执行,按照教程抓一个trace,应该就能看到功耗了。
注意事项:因为energy_model中power单位不确定,两个不同设备的power不可直接用于比较。
Battery counters 测电池消耗的电量
需要设备上存在电源管理硬件。大多数 Google Pixel 智能手机都支持
此功能。注意需要断开USB测试。
Sample config:
1 | data_sources: { |
perfetto的batt.charge_uah是当前电量,前后数值一减就是消耗的电量。
ODPM 测元器件的功耗
pixel 6 以上(含6)的pixel手机支持On-Device Power Rails Monitor (ODPM),在硬件层面做了更细粒度电源监控的支持,可以测量不同元器件的功耗。在平台级别,此数据是通过轮询 Android IPowerStats HAL 获得的。
Sample config:
1 | data_sources: { |
下面介绍如何使用ODPM对pixel 8功耗进行测量。
config.pbtx:
1 | buffers: { |
修改duration_ms
设置测量时间,修改battery_poll_ms
设置间隔。
执行命令得到trace文件
1 | perfetto --txt -c /data/local/tmp/config.pbtx -o /data/local/tmp/trace.perfetto-trace |
在perfetto web界面左侧导航栏选择Metrics,选择android_powrails,得到详细的功耗信息(如下图)。
其中,name
对应元器件名称,每个元器件都有energy_data
和avg_used_power_mw
,energy_data
中包含了每个间隔battery_poll_ms
的采样能耗,avg_used_power_mw
为duration_ms
时间内的平均功率。
在最末尾得到设备在duration_ms
时间内的总平均功率avg_total_used_power_mw
。
Reference
[1] https://perfetto.dev/docs/data-sources/battery-counters
[2] https://lpc.events/event/18/contributions/1842/attachments/1476/3126/LPC%202024%20-%20Wattson.pdf
[4] https://developer.android.com/studio/profile/power-profiler