Ondemand governor uses a sampling rate to check for load increase/decrease and change the cpu frequency. In stock kernel sampling rate is 40000us = 0.04s. This means that every 0.04 seconds ondemand governor checks for changes in system load and adjusts the cpu frequency.
In latests versions of Semaphore the sampling rate reduced to 10000uS (check every 0.01s). This leads to faster response to load changes but can also cause more frequency transitions and more overhead due to this processing.
Sampling down factor introduced in linux kernel in version 2.6.36-rc6 (stock is 2.6.35) helps to resolve this overhead.
David Niemi (the creator of sampling_down_factor) wrote:
Adds a new global tunable, sampling_down_factor. Set to 1 it makes no
changes from existing behavior, but set to greater than 1 (e.g. 100)
it acts as a multiplier for the scheduling interval for reevaluating
load when the CPU is at its top speed due to high load. This improves
performance by reducing the overhead of load evaluation and helping
the CPU stay at its top speed when truly busy, rather than shifting
back and forth in speed. This tunable has no effect on behavior at
lower speeds/lower CPU loads
Stock is missing the sampling down factor and I decided to patch Semaphore to support this (some other custom kernel supports sampling_down_factor).
Sampling_down_factor implementation and function is pretty simple. When the CPU is at its higher frequency (1000/1200/1300 in our case), delays the ondemand governor for longer period that the normal sampling one. For example, if the sampling down factor is 10 then when CPU reaches 1000/1200/1300MHz, it will stay there not for 0.01s but 10 x 0.01s = 0.1s. This is good when the system is heavy loaded ,because we have 10 times less checks (so less overhead due to the governor itself). It is also very good for system that does not depend on battery so much as our SGS.
I tested many sampling_down_factor values from 2 to 20 and I found that this tunable conflicts with newmail's check for deepsleep. So, I removed a part of newmail's patch and I left only the cap of max freqenct to 800MHz when the screen is off. Though, I couldn't decide for the optimal value of this factor. Bigger values leads to more responsiveness and effeciency but could drain battery faster (because the CPU stays in top frequency longer and maybe without the need).
So, I introduced a new tunable that I called sampling_down_momentum. This tunable tries to 'remember' previous load checks and increases sampling_down_factor on heavy load and decreases it on a 'quiet' system. As a result instead of deciding which is the optimal value of sampling_down_factor for our needs this approach try to do this automatically and constantly during run time.
By default I set sampling down factor to 4 and the sampling_down_momentum to a range from 0 - 16. The result is a variable sampling_down_factor from 4-20 proportional to system load during time.
The new tunable is configurable through sysfs (in /sys/devices/system/cpu/cpufreq/ondemand).
There are 2 new parameters:
sampling_down_max_momentum and sampling_down_momentum_sensititvity. The first one sets the maximum value that momentum can take and valid values are from 0 (disabled) to MAX_SAMPLING_DOWN_FACTOR - sampling_down_factor.
Please note that setting the momentum too high will cause the CPU to stay on highest frequency for long periods. For example setting this to its max value will cause gradually sampling_down_factor to reach its max value (100000). This means that CPU will stay for 1000s before ondemand check again for load changes.
The second one sets the sensitivity (how quick the momentum can change).
Valid values from 1 to MAX_SAMPLING_DOWN_MOMENTUM_SENSITIVITY (defined to 1000)
Since I read many topics in internet searching for the optimal value for sampling down factor, I believe that is can be patched in any linux kernel and not only for our phone.