[Nexus 7 Android Development] Stuphologist:
Making Sense of OnDemand

Down_differential is stuck at 10.

Bear with me, I'm trying to figure this out with a couple different Google search results. Check me, please.

Let's start with:

Down_differential: 10

Sampling_down_factor: 4

Sampling_rate 50000

Up_threshold: 85

Sampling_rate is misnamed, it's actually the sampling interval in microseconds. 50000 would be 50 milliseconds or 20 samples/second. This tells the CPU driver how often to check load and adjust the CPU freq. Smaller numbers improve CPU frequency conformance to load, but increase the overhead introduced by the sampling process. Larger numbers do the opposite.

Sampling_down_factor is applied when the CPU is maxed, and is a multiplier of sampling_rate. A value of 4 would change sampling_rate to 200000 which is 200 milliseconds or 5 samples/second when the CPU was maxed. The purpose of this is to reduce frequency hunting and sampling overhead when the processor is loaded. A kind of "I'm busy come back later" setting.

Up_threshold is a percentage, and is compared to the sampled CPU load. (For this to make sense the load value has to be the percentage of maximum load at the current CPU frequency, is that right?). Anyway, cross it going up and the CPU driver raises the CPU frequency to the next valid value above CPUFreq+((freq_step/100)*CPUMaxFreq). If that's higher than the CPUMaxFreq then it chooses CPUMaxFreq and uses sampling_down_factor to calculate the next sampling interval. Note that we don't have a way to adjust freq_step. What is it?

Down_differential is used in conjunction with up_threshold when the CPU driver figures out what the target CPU frequency should be. First it calculates the max_load_freq, which is the CPU freq that would be 100% loaded based on the current frequency and load. If the current frequency was 800 and the current load was 50% then the max_load_freq would be 400. To prevent the CPU freq from jumping back up in the next sample cycle after lowering it, it calculates a value: max_load_freq/(up_threshold - down_differential). In this case that would be 400/(.85-.10) = 400/.75 = 533. Lastly, it compares that value to the frequency table, and selects the next valid frequency higher than the calculated frequency. The end result is that the load at the new frequency is lower than the up_threshold, how much lower depends on the size of the down_differential and the next valid frequency in the frequency table. It's possible that this process (calculation and lookup) will result in the same value as the current frequency, Changing down_differential changes the size of the difference, after the frequency is changed, between the resulting load and the up_threshold load value.

So the effect would be:

Down_differential: Smaller numbers result in a lower target frequency, maybe stepping down faster and maybe saving battery a bit. Larger numbers push the target frequency up, improving performance and "butter".

Sampling_down_factor: Increasing this value from 1 causes the processor to linger longer at full power when loaded, improving performance at maximum load and frequency.

Sampling_rate: The lower the value the faster the frequency will change to follow load changes. The trade-off is nimbleness vs. the sampling/calculation/change process overhead. From what we've seen, the sweet spot seems to be 50000-100000.

Up_threshold: The lower the value the faster the processor climbs the frequency table, and the higher the calculated target frequency at a given load.

A "low" up_threshold and a "high" down_differential will tend to make the CPU kind of nervous and jumpy, especially if sampling_rate is "low". A "high" up_threshold and a "low" down_differential will make the CPU kind of sedate and laggy, especially if the sampling_rate is "high". Um...right?

Dave