• Stars
    star
    160
  • Rank 230,031 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created over 3 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Comprehensive CPU frequency performance/power benchmark

freqbench

Power usage in mW per frequency per cluster for Qualcomm Snapdragon 835, 855, and 765G

freqbench is a comprehensive CPU benchmark that benchmarks each CPU frequency step on each frequency scaling domain (e.g. ARM DynamIQ/big.LITTLE cluster). It is based on a minimal Alpine Linux userspace with the EEMBC CoreMark workload and a Python benchmark coordinator.

Results include:

  • Performance (CoreMark scores)
  • Performance efficiency (CoreMarks per MHz)
  • Power usage (in milliwatts)
  • Energy usage (in millijoules and joules)
  • Energy efficiency (ULPMark-CM scores: iterations per second per millijoule of energy used)
  • Baseline power usage
  • Time elapsed
  • CPU frequency scaling stats during the benchmark (for validation)
  • Diagnostic data (logs, kernel version, kernel command line, interrupts, processes)
  • Raw power samples in machine-readable JSON format (for postprocessing)

Why?

A benchmark like this can be useful for many reasons:

  • Creating energy models for EAS (Energy-Aware Scheduling)
  • Correcting inaccurate EAS energy models
  • Analyzing performance and power trends
  • Comparing efficiency across SoC and CPU generations
  • Improving performance and battery life of mobile devices by utilizing the race-to-idle phenomenon with efficient frequencies

Usage

It is possible to use freqbench with a stock kernel, but a custom kernel is highly recommended for accuracy. Stock OEM kernels are almost always missing features that the benchmark coordinator relies on for maximum accuracy. Custom kernel results are eligible for high accuracy classification, while stock kernel results are limited to low accuracy. Use a stock kernel at your own risk.

Custom kernel (recommended)

Set the following kernel config options:

CONFIG_NO_HZ_FULL=y
CONFIG_CPU_FREQ_TIMES=n  # may not exist
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_HZ_100=y

Example commit: kirin_defconfig: Configure for freqbench

If you have any commits that prevent userspace from controlling CPU affinities and utilization, frequencies, or anything of the sort, revert them for the benchmark to work properly. Here are some common examples of such commits in downstream kernels and their corresponding reverts:

Example freqbench kernel adaptations:

Compile and flash your new kernel. Note that Android will not work properly on this kernel, so make sure you take a backup of your old boot image to restore later.

If necessary, adjust the config parameters in config.sh. Most modern devices will not need any changes. Run pack-zip.sh and flash freqbench-installer.zip.

Unplug the device immediately, before the device starts booting. Do not try to wait for it to finish booting. Leaving the device plugged in will invalidate all power results.

Finally, wait until the device reboots itself. Do not touch the device, any of its buttons, or plug/unplug it during the test. It will be frozen on the bootloader splash screen; do not assume that it is broken. The benchmark is expected to take a long time; 1 hour is reasonable for a slower CPU.

Once the benchmark is done, retrieve the results from /cache/freqbench if your device has a cache partition, or /persist/freqbench otherwise (newer devices with A/B partitions don't have a cache partition).

If you are able to retrieve results, please consider contributing your results! It's very helpful for me to see how well freqbench is working, and enables anyone to analyze results across different SoCs that they don't have.

If you have any problems, check the troubleshooting section before opening an issue.

Manual boot image creation

Manually creating a new boot image with the kernel and ramdisk is only for advanced users. Use the AnyKernel3 installer unless you have good reason to do this.

Additional kernel config options:

CONFIG_CMDLINE="rcu_nocbs=0-7 isolcpus=1-7 nohz_full=1-7 loglevel=0 printk.devkmsg=on"
CONFIG_CMDLINE_EXTEND=y

If you don't have 8 CPU cores, adjust 0-7 to 0-<core count - 1> and 1-7 to 1-<core count - 1> where appropriate. Single-core CPUs are not supported. Be careful when adjusting the CPU sets as rcu_nocbs starts at CPU 0 while all other parameters start at CPU 1.

Create a boot image with your modified kernel and the freqbench ramdisk:

For boot image v0/v1 devices:

cd boot-v1
./unpack.sh path/to/normal/boot.img
./pack.sh
# New boot image will be created as new.img

For boot image v3 devices:

# Extract values from boot.img and update pack-img.sh accordingly
./pack-img.sh
# New boot image will be created as bench.img

After that, boot the modified image with fastboot boot if your device supports it, or flash it to the boot/recovery partition and boot that manually.

Results

After the benchmark finishes, results can be found in /cache/freqbench, /persist/freqbench, or /mnt/vendor/persist/freqbench, in that order of preference. The first path that exists on your device will be used. Human-readable results, raw machine-readable JSON data, and diagnostic information are included for analysis.

If you got this far, please consider contributing your results to help freqbench evolve and gather data about different SoCs:

Contributing results

If you run the benchmark on a SoC that is not already included, please contribute your results! It's very helpful for me to see how well freqbench is working, and enables anyone to analyze results across different SoCs that they don't have.

Contributing your results is easy:

  1. Fork this repository
  2. Add your entire results folder (not just one file from it) to results/socname/main, replacing socname with the model name of your SoC in lowercase
  3. Open a pull request

If you don't know your SoC's model name, search the name of your SoC (e.g. Snapdragon 855) and find the part number from the SoC manufacturer. You can also get it from your kernel source code and/or device.txt or cpuinfo.txt in the freqbench results. If you are still unsure, feel free to open an issue or guess the name.

Example names:

  • sm8150
  • sm8150ac
  • sm7250ab
  • exynos8895
  • mt6889

Identifiable information such as the device serial number is automatically redacted by freqbench, so it should not be a problem.

Don't worry about getting something wrong; I would much rather have results submitted with mistakes than nothing at all.

Post-processing

Several post-processing scripts, all written in Python and some using matplotlib, are available:

Legacy energy model

Create a legacy EAS energy model for use with older kernels.

Optional argument after path to results: key_type/value_type

Key types:

  • Frequency (default) - looks like 652800 or 2323200
  • Capacity - looks like 139 or 1024

You must use the correct key type for your kernel. When in doubt, refer to your original energy model and check which one the numbers look more like.

In general, downstream Qualcomm kernels will use the following key types depending on version:

  • 3.18: capacity
  • 4.4: capacity
  • 4.9: frequency
  • 4.14: frequency
  • 4.19: N/A (uses simplified energy model instead)

Modifying your kernel to switch from one to the other is left as an exercise for the reader.

Value types:

  • Power (default)
  • Energy (experimental, not recommended)

Do not change the value type unless you know what you're doing. The energy type only exists for testing purposes; do not expect it to work properly.

Once you have a full energy model generated, pick out the parts you need and incorporate them into your SoC device tree. In general, kernels 4.19 need capacity-dmips-mhz, while older kernels need efficiency when it comes to the contents of the CPU sections.

If you have an existing energy model that you want to use for idle and cluster costs, add it as an argument.

Example usage: ./legacy_energy_model.py results.json cap/power old_model.dtsi

Simplified energy model

Create a simplified EAS energy model for use with newer kernels.

Because voltages defined by the CPU frequency scaling driver cannot easily be accessed from userspace, you will need to provide them. Pass the voltage for each frequency step as an argument: cpu#.khz=microvolts

For Qualcomm SoCs on the msm-4.19 kernel, voltages can be obtained by booting the kernel (with or without freqbench doesn't matter, as long as you can get kernel logs) with this commit and searching for lines containing volt= in the kernel log.

For msm-4.9 and msm-4.14, the process is the same but with this commit and searching for open_loop_voltage instead.

Example usage: ./simplified_energy_model.py results.json 1.300000=580000 1.576000=580000 1.614400=580000 1.864000=644000 1.1075200=708000 1.1363200=788000 1.1516800=860000 1.1651200=888000 1.1804800=968000 6.652800=624000 6.940800=672000 6.1152000=704000 6.1478400=752000 6.1728000=820000 6.1900800=864000 6.2092800=916000 6.2208000=948000 7.806400=564000 7.1094400=624000 7.1401600=696000 7.1766400=776000 7.1996800=836000 7.2188800=888000 7.2304000=916000 7.2400000=940000

Efficient frequencies (experimental)

Derive a list of efficient frequencies for each cluster and create a new results.json with only those frequencies included.

Note that this script is experimental and may not produce optimal results. Manual tuning of the resulting frequency tables is recommended.

Example usage: ./efficient_freqs.py results.json eff_results.json

Filter frequencies

Create a new results.json with only the specified frequencies included.

Example usage: ./filter_freqs.py results.json filtered_results.json 1.1516800 1.1804800 6.1478400 6.1728000 6.2208000 7.1766400 7.2188800 7.2304000 7.2400000

Cross-CPU cluster graph

Performance (iter/s) across 835, 855, and 765G

Graph a value for each cluster across different SoCs/CPUs.

Arguments:

  • Add a SoC: SoC-1:soc1/results.json
  • Specify the value to graph: load/value (load is idle/active)
  • Set a flag: +flagname (soccolor, minscl)

Example usage: ./cross_cpu_cluster_graph.py 835:results/p2/main/results.json 855:results/zf6/main/results.json 855+:results/rog2/main/results.json 765G:results/p5/new-final/results.json active/power_mean +soccolor +minscl

Unified cluster graph

Performance (iter/s) across 765G little, big, and prime clusters

Graph a value for each cluster within the same SoC/CPU.

Example usage: ./unified_cluster_graph.py results.json coremark_score

Unified cluster column

Extract a value for each cluster within the same SoC/CPU and write the results into a CSV file.

Example usage: ./unified_cluster_csv.py results.json coremark_score cm_scores.csv

Troubleshooting

Kernel panics on boot

If your kernel panics on boot, disable CONFIG_CPU_FREQ_STAT. If that causes the kernel to fail to compile, cherry-pick cpufreq: Fix build with stats disabled.

Results vary too much

Check kernel.log, pre- and post-bench interrupts, running processes, and cpufreq stats from the results directory to diagnose the issue.

It's still running after an hour

If you have a slow CPU with a lot of frequency steps, this is not entirely unreasonable.

I want to debug it while it's running

freqbench offers interactive debugging via SSH over virtual USB Ethernet; the device acts as a USB Ethernet adapter and exposes an SSH server on the internal network. This feature can be enabled with the USB_DEBUG option in config.sh. It is disabled by default to avoid unnecessary USB setup that may influence benchmark results, so keeping it enabled for a final benchmark run is not recommended.

CONFIG_USB_CONFIGFS_RNDIS must be enabled for this feature to work. If your kernel does not have or use configfs for USB configuration, it will not work regardless of whether you have the RNDIS function enabled.

Once it's enabled, connect your device to a computer over USB. You should see something like this in your kernel logs if you are running Linux:

[7064379.627645] usb 7-3: new high-speed USB device number 114 using xhci_hcd
[7064379.772208] usb 7-3: New USB device found, idVendor=0b05, idProduct=4daf, bcdDevice= 4.14
[7064379.772210] usb 7-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[7064379.772211] usb 7-3: Product: Alpine GNU/Linux
[7064379.772211] usb 7-3: Manufacturer: Linux
[7064379.772212] usb 7-3: SerialNumber: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected]
[7064379.818904] rndis_host 7-3:1.0 usb0: register 'rndis_host' at usb-0000:47:00.1-3, RNDIS device, da:34:ab:99:c5:81
[7064379.870018] rndis_host 7-3:1.0 enp71s0f1u3: renamed from usb0

Run the SSH command in the serial number field to open a shell to the device. The password is empty, so just press enter when asked to provide a password.

More Repositories

1

safetynet-fix

Google SafetyNet attestation workarounds for Magisk
C++
6,032
star
2

android12-extensions

Enable and customize hidden features on Android 12.
Kotlin
429
star
3

fastboot.js

WebUSB implementation of the Android fastboot protocol
TypeScript
383
star
4

proton-clang

Proton Clang toolchains builds in the form of a continuously updating Git repository. Clone with --depth=1.
C
290
star
5

android-webinstall

Easy-to-use web installer for Android-based operating systems
Vue
245
star
6

adevtool

Android ROM device support and bringup tool, designed for maximum automation and speed.
TypeScript
215
star
7

base16-kitty

Base16 color scheme template for kitty
Mustache
192
star
8

pyrobud

A clean selfbot for Telegram with an emphasis on quality and practicality, designed to complement the official clients.
Python
126
star
9

cbackup

Fast & complete app + data backup script for Android
Shell
85
star
10

tipatch

A patcher for TWRP to backup internal storage/emulated SD card contents (photos, downloads, videos, etc).
Kotlin
70
star
11

touchpaint

An experimental Linux kernel module that demonstrates the lowest possible input latency on modern smartphones. Not for Android or production use.
C
63
star
12

colorkt

Modern color science library for Kotlin Multiplatform and Java
Kotlin
61
star
13

android_packages_apps_RepainterServicePriv

First-class custom ROM integration service for my Repainter app
Kotlin
58
star
14

linux-virtcontainer

Guest kernel for Nestbox (rootless VM containers on Android)
C
58
star
15

inter-font-pack

Magisk module that replaces Android's system fonts with Inter and other complementary fonts.
Shell
50
star
16

proton_kernel_redbull

Proton Kernel for the Pixel 5 (redfin) and Pixel 4a 5G (bramble), unified as redbull.
C
43
star
17

proton_zf6

Proton Kernel for the Asus Zenfone 6 (2019), codename Kirin and also known as I01WD and ZS630KL.
C
42
star
18

proton_bluecross

Proton Kernel for the Pixel 3 (blueline) and Pixel 3 XL (crosshatch) unified as bluecross. (discontinued)
C
36
star
19

proton_wsl2

Proton Kernel for the Windows Subsystem for Linux 2 (WSL 2). Highly experimental and always at the mercy of Windows Update.
C
26
star
20

base16-termux

Base16 for Termux
Mustache
26
star
21

aarch64-elf-gcc

GCC 9.2.0 + binutils 2.32 toolchain for x86_64 hosts, targeted for bare-metal (ELF / kernel-only) AArch64 systems.
C
25
star
22

proton_kernel_wahoo

Proton Kernel for the Pixel 2 (walleye) and Pixel 2 XL (taimen), unified as wahoo.
C
25
star
23

earlypilot

All-in-one server for monetizing software development with the early access supporter model
Kotlin
23
star
24

glcolortest

GLSL shader for testing color science and palette generation algorithms interactively
GLSL
23
star
25

kramflash

A fast & simple bootable GKI kernel flasher for boot image v2 and v3 devices.
Perl
20
star
26

benchkit

A developer-centric toolkit module for Android to facilitate in-depth profiling and benchmarking. MOVED to official Magisk module repo: https://github.com/Magisk-Modules-Repo/benchkit
Shell
19
star
27

ulog

Simple, fast, efficient logging facade for Android apps
Kotlin
17
star
28

mainline_kernel_easel

Mainline Linux kernel for the Pixel Visual Core image coprocessor (codename Easel/Monette Hill) found in the Pixel 2 and 3.
C
17
star
29

protonaosp.kdrag0n.dev

Website for @ProtonAOSP, a minimal Android fork focused on UI/UX and performance.
JavaScript
16
star
30

arm-eabi-gcc

GCC 9.2.0 + binutils 2.32 toolchain for x86_64 hosts, targeted for bare-metal (ELF / kernel-only) AArch32 systems.
C
15
star
31

touchpaint-android

Touchpaint Android app for latency testing, corollary to the Linux kernel module: https://github.com/kdrag0n/touchpaint
Kotlin
14
star
32

fxdsp

Fast and simple C++ DSP engine with high-quality effects. Originally built for PhantomAmp, an Android app for rootless system-wide audio effects.
C++
13
star
33

kdrag0n.dev

My personal website.
HTML
12
star
34

linux-m1

My experiments with Linux for the Apple M1 platform, based on Asahi and Corellium patches
C
11
star
35

app-utils

Select parts of my homegrown library for Android app development
Kotlin
10
star
36

drone-ssh-debug

A Drone plugin to enable remote build monitoring and debugging over SSH.
Shell
10
star
37

touchpaint-flutter

Touchpaint Flutter app for touch latency testing, corollary to the Android app: https://github.com/kdrag0n/touchpaint-android
Dart
9
star
38

velocity_tissot

Velocity Kernel for the Xiaomi Mi A1 (tissot). (discontinued)
C
9
star
39

eas_sdm660

An accurate, performant, and power-efficient EAS energy model for the Qualcomm Snapdragon 660 SoC (codename sdm660). THIS IS NOT A FULL EAS IMPLEMENTATION.
C
8
star
40

callbench

A program to measure the speed of simple time syscalls and vDSO calls, as well as basic in-memory file I/O using the mmap(2) and read(2) syscalls.
C
8
star
41

github-releases-proxy

GitHub Releases asset proxy for Cloudflare Workers
JavaScript
7
star
42

kbench

A Linux kernel microbenchmark suite.
Go
7
star
43

velocity_dream

Velocity Kernel for the Samsung Galaxy S8/S8+ (dreamlte/dream2lte). (discontinued)
C
7
star
44

blurtest

Test implementation of dual-filter Kawase blur in OpenGL ES 3.1, in the form of an Android app.
Kotlin
6
star
45

confirmationui-test

Simple app for testing Android Protected Confirmation (Confirmation UI)
Kotlin
6
star
46

serenade-calhacks23

TypeScript
6
star
47

aoc2021

My solutions for Advent of Code 2021
Python
5
star
48

DeviceSink

Android 11 device controls kitchen sink with all possible device types for testing.
Kotlin
5
star
49

caf4.14_kernel_wahoo

CAF 4.14 kernel for msm8998 wahoo
C
5
star
50

allocbench

Benchmark memory allocators realistically with techniques from Android, such as real-world trace replaying.
C++
5
star
51

msft-wsl2-kernel

An OLD and ABANDONED import of Microsoft's customized WSL2 Linux kernel with differentiated changes. Please use Microsoft's official up-to-date repository: https://github.com/microsoft/WSLv2-Linux-Kernel
C
5
star
52

aoc2020

My Advent of Code 2020 solutions in Rust and Python.
Python
4
star
53

passt-virtcontainer

C
4
star
54

caf_kernel_wahoo

CAF 4.4-based kernel for the Pixel 2 / XL (walleye/taimen), unified as wahoo. Note that this is a proof-of-concept which cannot fully boot Android due to encryption issues.
C
4
star
55

SwiftUI-AKList

Fast, stable, flexible SwiftUI wrapper for AppKit's NSOutlineView
Swift
3
star
56

speedscribble-htn2021

Hack the North 2021 team project: Draw against your friends in 1 minute!
JavaScript
3
star
57

stock_kernel_bluecross

A flashable stock kernel package for the Pixel 3 (blueline) and Pixel 3 XL (crosshatch) unified as bluecross/b1c1. Files extracted from Google factory images.
Shell
2
star
58

proprietary_vendor_asus

Proprietary vendor blobs for Asus devices, currently only the ZenFone 6 (I01WD).
Makefile
2
star
59

nanotap

A daemon that parses and dumps touch input events on Linux.
Go
2
star
60

structalgo

My implementations of various data structures and algorithms in C.
C
2
star
61

github-release-redirector

A simple Go web server that redirects a configured list of paths to the latest release asset on a GitHub repository.
Go
2
star
62

quicklock

Research project: Secure smart lock protocol with auditing and access control delegation.
Kotlin
2
star
63

archenemy

ArchEnemy Linux — a spin of Arch's official archiso live rescue disk with additional tools, tailored for my use.
Shell
2
star
64

hueflake-issues

Issue tracker for Hueflake
2
star
65

freebsd_easel

FreeBSD ported to the Pixel Visual Core (codename Easel/Monette Hill).
C
2
star
66

vardbg

A simple Python debugger and profiler, written for GCI 2019. Moved to CCExtractor.
Python
2
star
67

netbsd_easel

NetBSD ported to the Pixel Visual Core (codename Easel/Monette Hill).
2
star
68

aoc2022

Advent of Code 2022 solutions
Python
2
star
69

soca-treehacks24

JavaScript
2
star
70

gtcycles

A tool to measure the frequency of the generic timer on ARMv8 CPUs.
C
1
star
71

binderlat

A Go program to measure the latency of Binder IPC transactions on Android.
Go
1
star
72

slack-greeter

A simple Slack bot to greet new members of a workspace, written in Rust for GCI 2019.
Rust
1
star
73

platform_packages_modules_Connectivity

Java
1
star
74

pyrowall

Prototype Telegram bot with module and command discovery written in Go using gotgbot.
Go
1
star
75

biowave

A fast Discord bot prototype written in Go with module and command discovery.
Go
1
star
76

plushed

An Android plushie recognizer using Flutter and TensorFlow, made for GCI 2019.
Dart
1
star
77

flex-gestures

A failed attempt at a fluid iPhone X-like gestures app for Android that doesn't require root.
Kotlin
1
star
78

kdrag0n

Profile
1
star
79

gci-stats

A simple stats fetcher for Google Code-in that supports sending data to Graphite.
Python
1
star
80

android_device_asus_I01WD

Old Android 10 device tree for AOSiP on the Asus ZenFone 6.
C++
1
star
81

bluestone

A discontinued multi-purpose Discord bot written in Java, available for reference purposes.
Java
1
star
82

osrc_dream

Samsung OSRC updates for the Exynos Galaxy S8/+ (dreamlte/dream2lte) as Git commits.
C
1
star
83

HierarchialPerformanceTest.jl

Julia implementation of Non-parametric Hierarchial Performance Testing, a statistical technique for comparing the performance of different computers.
Julia
1
star