PowerMetricsKit

1.1.1

Swift package to retrieve realtime information on CPU energy consumption on Apple platforms using the CPU's Closed Loop Performance Controller (CLPC).
Androp0v/PowerMetricsKit

What's New

1.1.1

2024-06-14T07:21:04Z

Swift 6 support + fix compilation errors on iOS

PowerMetricsKit

PowerWidgetView

A package to retrieve realtime information on CPU energy consumption using the CPU's Closed Loop Performance Controller (CLPC) via proc_pidinfo.

How does it work?

Code related to energy measurements is under PowerWidget/. It works by using libproc's proc_pidinfo with the new PROC_PIDTHREADCOUNTS option, which returns a struct including per-thread energy measurements from the CPU's' CLPC, which in turn obtains the energy results from the Digital Power Estimator (DPE). The list of all threads is retrieved using task_threads with the PID of the current task (root privileges are required to invoke task_threads on other processes).

The libproc.h headers can't be imported on iOS, so they're reproduced at the beginning of sample_threads.c, as well as the result structs from the proc_pidinfo, using the definitions and documentation available in Apple's OSS Distributions repository for libproc.h.

Documentation

This package is documented using DocC. Please see PowerMetricsKit's documentation site or use Xcode > Product > Build documentation to compile the documentation for the package and view it locally.

DocumentationScreenshot

Results

When running a single app in the foreground, the results correlate well with wall power (measured with a USB-C amp/volt meter with the device charged to 100%), after substracting the energy used by the device while idling. On macOS, results are almost identical to the powermetrics output (this app reports slightly less power used, which makes sense since powermetrics also includes CPU power used by other apps and the OS).

The results are promising when experimenting with pathologic cases, and qualitatively match the predicted behavior. For example, making all threads wait forever on a spinlock makes the CPU utilization skyrocket (~100%/core) but power consumption remains very modest (less than 5W on a M3 Max w/16 cores), compared to ALU-heavy code like the simulation included with this app, that has lower CPU utilization (~30%) but uses much more power (~20W on M3 Max w/16 cores).

Limitations

Since without root privileges and/or specific entitlements only the energy of the threads from the same process can be measured, APIs that trigger work on a kernel thread (ie system calls) won't be accounted for in the power metrics of the app.

Compatibility

Tested on A14 Bionic or newer CPUs.

Generate documentation

Run this code on a Terminal window at the root of the PowerMetricsKit package to generate the documentation for this project used in GitHub pages.

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

References

Description

  • Swift Tools
View More Packages from this Author

Dependencies

  • None
Last updated: Thu Jul 04 2024 03:03:12 GMT-0900 (Hawaii-Aleutian Daylight Time)