PLEASE NOTE: These tweaks are meant for the Nexus 5X and other Snapdragon 808 devices ONLY. The approach taken to arrive at the governor values within the profiles in this thread or in this post below can still be followed for potentially any current Android phone on out there, but I will only support users of the Nexus 5X. There are simply too many variables and subtle differences between devices and I cannot test my tweaks on other devices because I'm a normal person and only own one phone.
To help increase battery life and/or the performance of our device through knowledgeable discussion and testing. This thread will embrace intelligible conversation, willingness to contribute and help others (to a point), and eagerness to educate ourselves further. I won't be holding anyone's hand. If you're not comfortable messing with your phone, this is not the place for you. I am also not a genius. I do not know everything about Android. I do like the rest of us, make mistakes and plan to learn from them. I hope that this discussion leads to all of us bettering our devices and us learning more about them, including myself. So if you find yourself in a position where you are more knowledgeable on a certain topic than another member (myself included), do not be afraid to help educate the other member in a professional manner (don't be a dick).
Our phone contains the Snapdragon 808 CPU. This CPU is built on the big.LITTLE architecture, meaning there are two clusters; a Big cluster and a LITTLE cluster. I spell the LITTLE cluster obnoxiously in all capitals because it emphasizes the architecture and the way that the two clusters are meant to be used. In a nutshell, the LITTLE cluster is used quite often. It's the workhorse cluster, crunching the numbers on every single task you ask of your phone, no matter how daunting. This cluster is comprised of four A53 cores. These cores are power efficient, but tend to be less efficient as their clock speeds go up. When a task is decided by the scheduler to be too large, or if things get too busy, the phone will pass on some of the workload to the Big cluster, which is comprised of two A57 cores. These cores are much more power hungry than the A53 cores, but tend to be more efficient as their clock speed rises. These cores can also accomplish more in less time, so this cluster can be thought of as a Burst CPU. In other words, when things get hot and heavy, the Big cluster steps in to tackle the workload and then goes right back to idle in an effort to save power. In fact, these cores are usually put to sleep when the screen is off.
The CPU Governor
The way the CPU behaves is controlled by something called a governor and we will mainly focus on the Interactive governor in this thread. The Interactive governor was created by Google for Android devices to be smooth yet more power efficient when compared to simpler governors like OnDemand used in older devices. The Interactive governor determines the CPU's behavior by several values or parameters that, with the help of root access, can be modified. It is strongly recommended that one reads Section 2.6 of the CPUFreq Documentation which details the inner-workings of the governor in a high-level and relatively easy to understand way. It is important to understand these values so that users can better comprehend what these profiles and tweaks do and why. I'll do my best to simplify the different values below:
- min_sample_time: The minimum amount of time to spend at a particular frequency before ramping down. This value is defined in microseconds, meaning if it were set to '50000', the CPU has to spend 50ms or 1/20th of a second at a particular frequency before ramping down. This is to prevent the CPU from behaving too erratically, which can be a drain on power. The higher the value, the longer the CPU must stay at that frequency, and vice versa.
- timer_rate: Confusingly, when compared to the value above, this is basically the sample rate. This value, also defined in microseconds, determines how long the CPU must take to evaluate the current workload. The lower the value, the more responsive the CPU will be to the current workload of the phone. This results in the CPU clock speed changing quite often. The higher the value, the more lethargic the CPU becomes. This is an important value because striking a balance between hectic behavior and lackadaisical behavior can make a difference when it comes to performance and battery life.
- go_hispeed_load: Load is calculated by the CPU's scheduler. And while I won't be getting into that here, it is an interesting read. When the CPU load reaches or exceeds this value, the CPU will immediately jumped to the defined frequency. This value is on a scale of 0-100.
- hispeed_freq: This is the frequency that the CPU will jump to when go_hispeed_load is reached or exceeded. The value is defined in kHz. Ex. 960 MHz = 960000 kHz
- target_loads: Arguably the most important parameter of the Interactive governor. This determines how the CPU behaves and its eagerness to jump to the next frequency based on CPU load. The format for this can be a load value or a series of frequencies with respective target loads. ex.
75 672000:30 960000:85 1440000:100In the latter example, there is a target_load defined for any frequency below 672 MHz. This means for the CPU to raise itself to the next frequency step, the current workload must be calculated by the scheduler to be at least 75 (out of 100). Each time the CPU frequency is raised, the workload value is reevaluated and the CPU will keep raising the clock speeds until the workload is lower than the defined target_load. When the CPU reaches 672 MHz, the CPU can ONLY step up to the next frequency if the current workload exceeds 30. Note, that at any time, if the workload exceeds go_hispeed_load that the CPU jump to the hispeed if it is not already running at a higher frequency than hispeed_freq. For every frequency after 672 MHz, the target_load is also 30, until it reaches 960 MHz. So, although many of the profiles included here define a target_load for every single frequency, it is not compulsory.
- above_hispeed_delay: Measured, again, in microseconds, this parameter defines an extra amount of time the phone must spend evaluating the workload (sample rate) ON TOP OF the timer_rate. For example, the hispeed_freq is 960 MHz and the timer_rate is 50000 (50ms). If above_hispeed_delay is defined as 20000 or 20ms, then in order for the CPU to jump to the next frequency above 960 MHz, the CPU must spend a total of 70ms evaluating the workload. This is to prevent the CPU from ramping up too aggressively.
- max_freq_hysteresis: This value tells the CPU how long it must maintain the highest achievable frequency when it has reached said frequency. For example, if the maximum frequency of the CPU is 1632 MHz, and the CPU reaches said frequency, then it MUST stay at this frequency for the amount of time defined in max_freq_hysteresis. This value is in microseconds and is usually used to prevent the CPU from ramping back down before another chunk of the workload is reached, resulting in poor performance.
In almost every case, you'll want to disable touchboost. This is to save power and it is vital to the correct operation of the profiles in this thread. Instead of using Touchboost, the use of Input Boost is highly recommended. Input Boost is an easy topic to grasp, as it's basically a way of boosting the CPU clocks to a certain frequency whenever you interact with the screen. This provides for a fluid user experience and also allows for the CPU to idle while simply staring at the phone or when the screen is on. There are three values that we will focus on:
- Input Boost Enabled: Self Explanatory, but you're going to want to make sure this is set to '1' or 'enabled'.
- Input Boost Frequency: This defines which cores are boosted and to what frequency they're boosted to. It is common practice to only boost the LITTLE cluster, for efficiency reasons. The value is in a core#:frequency(in kHz) format. ex.
0:672000 1:672000 2:672000 3:672000 4:0 5:0This means that the entire LITTLE cluster will be boosted to 672 MHz upon interacting with the screen if the CPU frequency does not already exceed that value. Please note that the cores are numbered starting at 0, not 1. The LITTLE cores are always first (0-3), which the big cores are always last (4 and 5).
- Input Boost Milliseconds: This determines how long the cores will be boosted, in milliseconds. If the value is set to, say, 40, the cores will be boosted to at least the defined frequency for the entire duration and 40 milliseconds after the user is done interacting with the phone.
Hopefully now you have a better understanding of the different parts of the Interactive governor. The next step is either trying different profiles or tweaking the governors yourself. I'd rather not link anything to XDA, but because of the shear amount of space that the write-up consumes, SoniCron's guide for customizing the Interactive Governor to your liking is defined here.
Originally, people would share the values and rely on others to copy the values correctly to their phones. I came up with the simple idea to apply them via a bash script, which could be shared with others and provide an easy one-click kind of way to apply a set of settings. This approach is sometimes preferred because conditional statements and other logic can be written into the scripts, like detecting over and underclocking. These scripts must be run at least once and then the settings marked to be applied on boot in any Kernel Management app of your choosing. This avenue is attractive for those that prefer not to use EXKM.
These are basically the bash scripts with one extra line delaying the execution for an additional 40 seconds. These scripts, like all init.d and su.d scripts are run on boot. This option is attractive to people that prefer not to use a Kernel App to apply the CPU settings. These scripts require a custom kernel that supports init.d or su.d scripts and therefore do not work for everyone.
Thanks to ElementalX Kernel Developer, flar2, sharing and changing governor settings on the fly has never been easier. Utilizing the EX Kernel Manager app one can apply any number of included profiles, create their own, or download and install a profile of their choice and then load it in one click. Unfortunately there are several drawbacks to this approach. The app costs money, custom profiles do not save things like input boost and current governor, requiring the user to edit their own profile in a text editor, and logic/conditional statements cannot be written into these profiles like they can be in the bash scripts.
I hope this sheds some light on how these profiles and scripts work. Please head to post #2 for a list of Current Profiles and their descriptions. This post and the post below will be consistently updated for legibility and so that they contain the most up-to-date information. I will, of course, monitor this thread the best I can. However, I work a 9-5 during the week and I tend to disappear on weekends, because social life.