[Samsung Galaxy Nexus] boype:
Knowledge base: ondemandplus guide

This post serves as additional information about ondemandplus and its variables. It is linked to the OP's knowledge-base.

ondemandplus is an ondemand- and interactive-based governor that has additional power-saving capabilities while maintaining very snappy performance. While the interactive governor provides a modern and sleek framework, the scaling logic has been been re-written completely.

Basics about the governor's scaling logic

When the screen is on: First of all, the governor checks the CPU load for the currently set CPU frequency during the last timer cycle. If the CPU load (measured in percent) is higher than the up_threshold, the governor will increase the CPU frequency. Originally in plain ondemand, the CPU frequency is immediately increased to the maximum supported frequency. If the CPU load is lower than up_threshold - down_differential, the governor will decrease the CPU frequency. The frequency to scale down to is calculated like this: (current CPU frequency * CPU load) / up_threshold - down_differential.

In ondemandplus, the downscaling behavior is only very slightly modified. However, the upscaling has been modified to not scale up to maximum frequency immediately. By means of the inter_lofreq, inter_hifreq and inter_staycycles sysfs variables, upscaling is 'dampened' to save battery - a kind of 'barrier' is set, which first has to be breached. For example: inter_lofreq is 729 MHz, inter_hifreq is 1036 MHz and inter_staycycles is 3. This will result in the following behavior when a frequency increase is triggered: In the first timer cycle with high CPU load, the frequency will be set to inter_lofreq (729 MHz). If the load remains high in the next timer cycle, the frequency will be further increased to inter_hifreq (1036 MHz). If the CPU load is still high, inter_hifreq is kept until the inter_staycycles value is reached. In this example, the CPU has been scaled up twice so far, so one more timer cycle of high CPU load is necessary to scale to the maximum CPU frequency. And now - as already indicated - after the a third timer cycle with high CPU load, inter_hifreq can finally be left behind for higher CPU frequencies.

The sysfs variable staycycles_resetfreq merely controls when the staycycle counter is reset to 0, thus effectively re-applying the 'barrier'. So, if staycycles_resetfreq is set to 500 MHz (which equals a sysfs value of 500000), the upscaling barrier is re-established when the CPU is scaled down below 500 MHz.

Information added June 17, 2013: Ondemandplus now uses an algorithm to dynamically set the timer_rate in order to save battery in low- and constant-load-scenarios. The way the governor does this is simple but effective:

Each 5 timer cycles, the governor checks the last 5 requested CPU frequencies and calculates the average of them. When the next requested CPU frequency is within a 15% range of this average, the timer_rate is throttled. This only counts for all CPU frequencies below the inter_lofreq. For frequencies above inter_lofreq, the next requested CPU frequency has to match the average exactly to throttle the timer_rate.

When the next requested frequency is not close enough to the average anymore, the timer_rate is set back to its normal value.

When the screen is off: CPU scaling is way simpler when the screen is off. When the CPU load is higher than up_threshold, the governor will simply scale up to the next-highest frequency. Of course, it can not be scaled to a higher CPU frequency than the maximum screen-off frequency.

Downscaling works pretty much the same way. When the CPU load is below up_threshold - down_differential, the next lower CPU frequency will be the target.

Governor sysfs tuneables and their effects

timer_rate: The interval in microseconds in which the CPU load is measured. If set to 30000 for example, there will be a check (and maybe a frequency change if necessary) every 0.030 seconds.

up_threshold: If the measured CPU load is higher than this value, the governor will scale the frequency up. Value is in percent. Higher values can cause slower upscaling and maybe slight lags.

down_differential: If the measured CPU load is lower than up_threshold - down_differential, the governor will scale the frequency down. Lower values will cause faster downscaling.

inter_lofreq: The first intermediate frequency to scale to if the CPU load is high.

inter_hifreq: The second intermediate frequency to scale to if the CPU load is high. Can be equal to inter_lofreq.

inter_staycycles: The amount of timer cycles under consistently high CPU load that are necessary to be able to finally scale up to the maximum CPU frequency. 1 timer cycle equals the timer_rate value. If set to 0, the intermediate frequencies are not used, instead the governor will scale up to the maximum CPU frequency immediately.

staycycles_resetfreq: When the CPU frequency goes below this value, the timer cycle counter (counting the high-load-cycles until inter_staycycles is reached) is reset to 0. This effectively re-establishes the intermediate frequency barrier. Value cannot be set higher than inter_lofreq.