Commit f1c8e410cdac5df42a7806e49efde2859a10fecd
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 | /* |