Commit f1c8e410cdac5df42a7806e49efde2859a10fecd

Authored by Rafael J. Wysocki
1 parent 12b65eadf0

cpuidle: menu: Avoid computations when result will be discarded

If the minimum interval taken into account in the average computation
loop in get_typical_interval() is less than the expected idle
duration determined so far, the resultant average cannot be greater
than that value as well and the entire return result of the function
is going to be discarded anyway going forward.

In that case, it is a waste of time to carry out the remaining
computations in get_typical_interval(), so avoid that by returning
early if the minimum interval is not below the expected idle duration.

No intentional changes of behavior.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Showing 1 changed file with 16 additions and 3 deletions Side-by-side Diff

drivers/cpuidle/governors/menu.c
... ... @@ -196,10 +196,11 @@
196 196 * of points is below a threshold. If it is... then use the
197 197 * average of these 8 points as the estimated value.
198 198 */
199   -static unsigned int get_typical_interval(struct menu_device *data)
  199 +static unsigned int get_typical_interval(struct menu_device *data,
  200 + unsigned int predicted_us)
200 201 {
201 202 int i, divisor;
202   - unsigned int max, thresh, avg;
  203 + unsigned int min, max, thresh, avg;
203 204 uint64_t sum, variance;
204 205  
205 206 thresh = UINT_MAX; /* Discard outliers above this value */
... ... @@ -207,6 +208,7 @@
207 208 again:
208 209  
209 210 /* First calculate the average of past intervals */
  211 + min = UINT_MAX;
210 212 max = 0;
211 213 sum = 0;
212 214 divisor = 0;
213 215  
... ... @@ -217,8 +219,19 @@
217 219 divisor++;
218 220 if (value > max)
219 221 max = value;
  222 +
  223 + if (value < min)
  224 + min = value;
220 225 }
221 226 }
  227 +
  228 + /*
  229 + * If the result of the computation is going to be discarded anyway,
  230 + * avoid the computation altogether.
  231 + */
  232 + if (min >= predicted_us)
  233 + return UINT_MAX;
  234 +
222 235 if (divisor == INTERVALS)
223 236 avg = sum >> INTERVAL_SHIFT;
224 237 else
... ... @@ -325,7 +338,7 @@
325 338 /*
326 339 * Use the lowest expected idle interval to pick the idle state.
327 340 */
328   - predicted_us = min(predicted_us, get_typical_interval(data));
  341 + predicted_us = min(predicted_us, get_typical_interval(data, predicted_us));
329 342  
330 343 if (tick_nohz_tick_stopped()) {
331 344 /*