blob: 5dce785aee8e9b2f0eda186fc8da5bf8bf064050 [file] [log] [blame]
<html devsite>
<head>
<title>Identifying Capacity-Related Jank</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>Capacity is the total amount of some resource (CPU, GPU, etc.) a device
possesses over some amount of time. This page describes how to identify and
address capacity-related jank issues.</p>
<h2 id="governor">Governor slow to react</h2>
<p>To avoid jank, the CPU frequency governor needs to be able to respond quickly
to bursty workloads. Most UI applications follow the same basic pattern:</p>
<ol>
<li>User is reading the screen.</li>
<li>User touches the screen: taps a button, scrolls, etc.</li>
<li>Screen scrolls, changes activity, or animates in some way in response to
input.</li>
<li>System quiesces as new content is displayed.</li>
<li>User goes back to reading the screen.</li>
</ol>
<p>Pixel and Nexus devices implement touch boost to modify CPU frequency
governor (and scheduler) behavior on touch. To avoid a slow ramp to a high clock
frequency (which could cause the device to drop frames on touch), touch boost
usually sets a frequency floor on the CPU to ensure plenty of CPU capacity is
available on touch. A floor lasts for some amount of time after touch (usually
around two seconds).</p>
<p>Pixel also uses the schedtune cgroup provided by Energy Aware Scheduling
(EAS) as an additional touch boost signal: Top applications get additional
weight via schedtune to ensure they get enough CPU capacity to run quickly. The
Nexus 5X and 6P have a much bigger performance gap between the little and big
CPU clusters (A53 and A57, respectively) than the Pixel with the Kryo CPU. We
found that the little CPU cluster was not always adequate for smooth UI
rendering, especially given other sources of jitter on the device.</p>
<p>Accordingly, on the Nexus 5X and 6P, touch boost modifies the scheduler
behavior to make it more likely for foreground applications to move to the big
cores (this is conceptually similar to the floor on CPU frequency). Without the
scheduler change to make foreground applications more likely to move to the big
CPU cluster, foreground applications may have insufficient CPU capacity to
render until the scheduler decided to load balance the thread to a big CPU core.
By changing the scheduler behavior during touch boost, it is more likely for a
UI thread to immediately run on a big core and avoid jank while not forcing it
to always run on a big core, which could have severe impacts on power
consumption.</p>
<h2 id="thermal-throttling">Thermal throttling</h2>
<p>Thermal throttling occurs when the device must reduce its overall thermal
output, usually performed by reducing CPU, GPU, and DRAM clocks. Unsurprisingly,
this often results in jank as the system may no longer be able to provide enough
capacity to render within a given timeslice. The only way to avoid thermal
throttling is to use less power. There are not a lot of ways to do this, but
based on our experiences with past SOCs, we have a few recommendations for
system vendors.</p>
<p>First, when building a new SOC with heterogeneous CPU architectures, ensure
the performance/W curves of the CPU clusters overlap. The overall performance/W
curve for the entire processor should be a continuous line. Discontinuities in
the perf/W curve force the scheduler and frequency governor to guess what a
workload needs; to prevent jank, the scheduler and frequency governor err on
the side of giving the workload more capacity than it requires. This results in
spending too much power, which contributes to thermal throttling.</p>
<p>Imagine a hypothetical SOC with two CPU clusters:</p>
<ul>
<li>Cluster 1, the little cluster, can spend between 100-300mW and scores
100-300 in a throughput benchmark depending on clocks.</li>
<li>Cluster 2, the big cluster, can spend between 1000 and 1600mW and scores
between 800 and 1200 in the same throughput benchmark depending on clocks.</li>
</ul>
<p>In this benchmark, a higher score is faster. While not more desirable than
slower, faster == greater power consumption.</p>
<p>If the scheduler believes a UI workload would require the equivalent of a
score of 310 on that throughput benchmark, its best option to avoid jank is to
run the big cluster at the lowest frequency, wasting significant power. (This
depends on cpuidle behavior and race to idle; SOCs with continuous perf/W curves
are easier to optimize for.)</p>
<p>Second, use cpusets. Ensure you have enabled cpusets in your kernel and in
your <code>BoardConfig.mk</code>. You must also set up the actual cpuset
assignments in your device-specific <code>init.rc</code>. Some vendors leave
this disabled in their BSPs in the hopes they can use other hints to influence
scheduler behavior; we feel this doesn't make sense. cpusets are useful for
ensuring load balancing between CPUs is done in a way that reflects what the
user is actually doing on the device.</p>
<p>ActivityManager assigns apps to different cpusets based on the relative
importance of those apps (top, foreground, background), with more important
applications getting more access to CPU cores. This helps ensure quality of
service for foreground and top apps.</p>
<p>cpusets are useful on homogeneous CPU configurations, but you should not ship
a device with a heterogeneous CPU configuration without cpusets enabled. Nexus
6P is a good model for how to use cpusets on heterogeneous CPU configurations;
use that as a basis for your own device's configuration.</p>
<p>cpusets also offer power advantages by ensuring background threads that are
not performance-critical never get load balanced to big CPU cores, where they
could spend significantly more power without any user-perceived benefit. This
can help to avoid thermal throttling as well. While thermal throttling is a
capacity issue, jitter improvements have an outsize impact on UI performance
when thermal throttling. Because the system will be running closer to its
ability to render 60FPS, it takes less jitter to cause a dropped frame.</p>
</body>
</html>