PowerMetricsKit

PowerWidgetView

一个使用 CPU 的闭环性能控制器 (CLPC) 通过 proc_pidinfo 获取 CPU 能量消耗实时信息的软件包。

它是如何工作的?

与能量测量相关的代码位于 PowerWidget/ 下。它的工作原理是使用 libprocproc_pidinfo 以及新的 PROC_PIDTHREADCOUNTS 选项,该选项返回一个 struct,其中包含来自 CPU 的 CLPC 的每个线程的能量测量值,而 CLPC 又从数字功率估算器 (DPE) 获取能量结果。使用当前任务的 PID,使用 task_threads 来检索所有线程的列表(需要在其他进程上调用 task_threads 需要 root 权限)。

libproc.h 标头无法在 iOS 上导入,因此它们在 sample_threads.c 的开头被重新定义,以及来自 proc_pidinfo 的结果 struct,使用了 Apple 的 OSS Distributions 仓库中 libproc.h 的定义和文档

文档

此软件包使用 DocC 进行文档化。请参阅 PowerMetricsKit 的文档站点或使用Xcode > Product > Build documentation来编译软件包的文档并在本地查看。

DocumentationScreenshot

结果

当在前台运行单个应用程序时,在减去设备空闲时使用的能量后,结果与墙电电源(使用 USB-C 安培/伏特计测量,设备充电至 100%)良好相关。在 macOS 上,结果几乎与 powermetrics 输出相同(此应用程序报告的功耗略低,这是有道理的,因为 powermetrics 还包括其他应用程序和操作系统使用的 CPU 功耗)。

在试验病态情况时,结果很有希望,并且在质量上与预测的行为相符。例如,使所有线程永远等待一个自旋锁会使 CPU 利用率飙升(~100%/核心),但功耗仍然非常适中(在具有 16 个核心的 M3 Max 上小于 5W),相比之下,像此应用程序包含的模拟这样的 ALU 密集型代码,CPU 利用率较低(~30%)但使用更多的电力(在具有 16 个核心的 M3 Max 上约为 20W)。

局限性

由于在没有 root 权限和/或特定权利的情况下,只能测量来自同一进程的线程的能量,因此在内核线程上触发工作的 API(即系统调用)将不会在应用程序的功耗指标中计算在内。

兼容性

已在 A14 Bionic 或更新的 CPU 上进行了测试。

生成文档

在 PowerMetricsKit 软件包的根目录下,在终端窗口中运行此代码,以生成 GitHub 页面中使用的此项目的文档。

swift package --allow-writing-to-directory docs generate-documentation --target PowerMetricsKit --disable-indexing --transform-for-static-hosting --hosting-base-path PowerMetricsKit --output-path docs

参考