4141 * the C state is required to actually break even on this cost. CPUIDLE
4242 * provides us this duration in the "target_residency" field. So all that we
4343 * need is a good prediction of how long we'll be idle. Like the traditional
44- * menu governor, we start with the actual known "next timer event" time.
44+ * menu governor, we take the actual known "next timer event" time.
4545 *
4646 * Since there are other source of wakeups (interrupts for example) than
4747 * the next timer event, this estimation is rather optimistic. To get a
5050 * duration always was 50% of the next timer tick, the correction factor will
5151 * be 0.5.
5252 *
53- * menu uses a running average for this correction factor, however it uses a
54- * set of factors, not just a single factor. This stems from the realization
55- * that the ratio is dependent on the order of magnitude of the expected
56- * duration; if we expect 500 milliseconds of idle time the likelihood of
57- * getting an interrupt very early is much higher than if we expect 50 micro
58- * seconds of idle time. A second independent factor that has big impact on
59- * the actual factor is if there is (disk) IO outstanding or not.
60- * (as a special twist, we consider every sleep longer than 50 milliseconds
61- * as perfect; there are no power gains for sleeping longer than this)
62- *
63- * For these two reasons we keep an array of 12 independent factors, that gets
64- * indexed based on the magnitude of the expected duration as well as the
65- * "is IO outstanding" property.
53+ * menu uses a running average for this correction factor, but it uses a set of
54+ * factors, not just a single factor. This stems from the realization that the
55+ * ratio is dependent on the order of magnitude of the expected duration; if we
56+ * expect 500 milliseconds of idle time the likelihood of getting an interrupt
57+ * very early is much higher than if we expect 50 micro seconds of idle time.
58+ * For this reason, menu keeps an array of 6 independent factors, that gets
59+ * indexed based on the magnitude of the expected duration.
6660 *
6761 * Repeatable-interval-detector
6862 * ----------------------------
6963 * There are some cases where "next timer" is a completely unusable predictor:
7064 * Those cases where the interval is fixed, for example due to hardware
71- * interrupt mitigation, but also due to fixed transfer rate devices such as
72- * mice.
65+ * interrupt mitigation, but also due to fixed transfer rate devices like mice.
7366 * For this, we use a different predictor: We track the duration of the last 8
74- * intervals and if the stand deviation of these 8 intervals is below a
75- * threshold value, we use the average of these intervals as prediction.
76- *
67+ * intervals and use them to estimate the duration of the next one.
7768 */
7869
7970struct menu_device {
@@ -116,53 +107,52 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
116107 */
117108static unsigned int get_typical_interval (struct menu_device * data )
118109{
119- int i , divisor ;
120- unsigned int min , max , thresh , avg ;
121- uint64_t sum , variance ;
122-
123- thresh = INT_MAX ; /* Discard outliers above this value */
110+ s64 value , min_thresh = -1 , max_thresh = UINT_MAX ;
111+ unsigned int max , min , divisor ;
112+ u64 avg , variance , avg_sq ;
113+ int i ;
124114
125115again :
126-
127- /* First calculate the average of past intervals */
128- min = UINT_MAX ;
116+ /* Compute the average and variance of past intervals. */
129117 max = 0 ;
130- sum = 0 ;
118+ min = UINT_MAX ;
119+ avg = 0 ;
120+ variance = 0 ;
131121 divisor = 0 ;
132122 for (i = 0 ; i < INTERVALS ; i ++ ) {
133- unsigned int value = data -> intervals [i ];
134- if (value <= thresh ) {
135- sum += value ;
136- divisor ++ ;
137- if (value > max )
138- max = value ;
139-
140- if (value < min )
141- min = value ;
142- }
123+ value = data -> intervals [i ];
124+ /*
125+ * Discard the samples outside the interval between the min and
126+ * max thresholds.
127+ */
128+ if (value <= min_thresh || value >= max_thresh )
129+ continue ;
130+
131+ divisor ++ ;
132+
133+ avg += value ;
134+ variance += value * value ;
135+
136+ if (value > max )
137+ max = value ;
138+
139+ if (value < min )
140+ min = value ;
143141 }
144142
145143 if (!max )
146144 return UINT_MAX ;
147145
148- if (divisor == INTERVALS )
149- avg = sum >> INTERVAL_SHIFT ;
150- else
151- avg = div_u64 (sum , divisor );
152-
153- /* Then try to determine variance */
154- variance = 0 ;
155- for (i = 0 ; i < INTERVALS ; i ++ ) {
156- unsigned int value = data -> intervals [i ];
157- if (value <= thresh ) {
158- int64_t diff = (int64_t )value - avg ;
159- variance += diff * diff ;
160- }
161- }
162- if (divisor == INTERVALS )
146+ if (divisor == INTERVALS ) {
147+ avg >>= INTERVAL_SHIFT ;
163148 variance >>= INTERVAL_SHIFT ;
164- else
149+ } else {
150+ do_div (avg , divisor );
165151 do_div (variance , divisor );
152+ }
153+
154+ avg_sq = avg * avg ;
155+ variance -= avg_sq ;
166156
167157 /*
168158 * The typical interval is obtained when standard deviation is
@@ -177,25 +167,40 @@ static unsigned int get_typical_interval(struct menu_device *data)
177167 * Use this result only if there is no timer to wake us up sooner.
178168 */
179169 if (likely (variance <= U64_MAX /36 )) {
180- if (((( u64 ) avg * avg > variance * 36 ) && ( divisor * 4 >= INTERVALS * 3 ))
181- || variance <= 400 ) {
170+ if ((avg_sq > variance * 36 && divisor * 4 >= INTERVALS * 3 ) ||
171+ variance <= 400 )
182172 return avg ;
183- }
184173 }
185174
186175 /*
187- * If we have outliers to the upside in our distribution, discard
188- * those by setting the threshold to exclude these outliers , then
176+ * If there are outliers, discard them by setting thresholds to exclude
177+ * data points at a large enough distance from the average , then
189178 * calculate the average and standard deviation again. Once we get
190- * down to the bottom 3/4 of our samples, stop excluding samples.
179+ * down to the last 3/4 of our samples, stop excluding samples.
191180 *
192181 * This can deal with workloads that have long pauses interspersed
193182 * with sporadic activity with a bunch of short pauses.
194183 */
195- if ((divisor * 4 ) <= INTERVALS * 3 )
184+ if (divisor * 4 <= INTERVALS * 3 ) {
185+ /*
186+ * If there are sufficiently many data points still under
187+ * consideration after the outliers have been eliminated,
188+ * returning without a prediction would be a mistake because it
189+ * is likely that the next interval will not exceed the current
190+ * maximum, so return the latter in that case.
191+ */
192+ if (divisor >= INTERVALS / 2 )
193+ return max ;
194+
196195 return UINT_MAX ;
196+ }
197+
198+ /* Update the thresholds for the next round. */
199+ if (avg - min > max - avg )
200+ min_thresh = min ;
201+ else
202+ max_thresh = max ;
197203
198- thresh = max - 1 ;
199204 goto again ;
200205}
201206
0 commit comments