The cpufreq subsystem allows for dynamic voltage and frequency scaling (DVFS), where a CPU's relative performance (and thus power consumption) can be tuned to the current workload.
This document outlines how to interact with the cpufreq subsystem from userspace to set a CPU's frequency as well as how to pin tasks to particular CPUs.
Linux exposes this information through `/proc/cpuinfo':
`/proc/cpuinfo'
# cat /proc/cpuinfo processor : 0 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 0 processor : 1 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd07 CPU revision : 0 processor : 2 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd07 CPU revision : 0 processor : 3 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 0 processor : 4 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 0 processor : 5 BogoMIPS : 100.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: AArch64 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 0 Hardware : ARM Juno development board (r0)
Here the `processor' number is the index the kernel uses for the CPU and corresponds to those used in `/sys/', i.e. processor 1 in the above output corresponds to `/sys/devices/system/cpu/cpu1/'.
`processor'
`/sys/'
`/sys/devices/system/cpu/cpu1/'
The `CPU part' is the primary part number of the CPU as read from the MIDR_EL1 system register. We can consult the Technical Reference Manual (TRM) of a processor to find the expected part number; for a Cortex-A53 this is 0xd03, for a Cortex-A57 this is 0xd07, and for a Cortex-A72 this is 0xd08.
`CPU part'
MIDR_EL1
0xd03
0xd07
0xd08
So in the example above CPUs 0, 3, 4, and 5 are Cortex-A53s because their part number is 0xd03, while CPUs 1 and 2 are Cortex-A57 cores because their part number is 0xd07.
In Linux each process has a CPU affinity describing which CPUs that process is allowed to run on in an SMP system; by default this is "all CPUs" but we can use the `taskset' command to choose the affinity.
`taskset'
Example 1 - Run `ls /lib' only on CPU 5 (Cortex_A53_4)
`ls /lib'
# taskset -c 5 ls /lib
Example 2 - Run `grep -i joe users.txt' allowed only on CPUs 1 and 2 (the two Cortex-A57 cores):
`grep -i joe users.txt'
# taskset -c 1,2 grep -i joe users.txt
Example 3 - Run `ping 192.0.0.1' allowed on all CPUs:
`ping 192.0.0.1'
# taskset -c 0-5 ping 192.0.0.1
Note: If the `tasket' command is not available, try using either the Android or OpenEmbedded LAMP filesystem.
`tasket'
cpufreq allows for the clock speed of a CPU to be adjusted on-the-fly in order to adjust to current load demands; by reducing the clock speed while a processor is idle we can drastically reduce power consumption and heat generation.
To read the current operating frequency of a CPUm for example CPU 4:
# cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq 1150000
You can obtain a list of available frequencies like so:
# cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_available_frequencies 600000 900000 1150000
And to select a frequency:
# echo 900000 > /sys/devices/system/cpu/cpu4/cpufreq/scaling_setspeed
Note: For Juno r1 boards the Cortex-A53 cores are limited to 650MHz only.
The rules used by the kernel for dynamically adjusting the frequency are defined by the cpufreq scaling governor.
The governor defines the power characteristics of the system's CPUs which in turn affects CPU performance. Each governor has its own unique behaviour, purpose, and use case suitability.
The available governors can be listed like so:
# cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_available_governors ondemand userspace interactive performance
To select a governor:
# echo userspace > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor
More information regarding cpufreq scaling governors can be found here.