Skip to content

Commit

Permalink
cpuidle: menu: Avoid computations when result will be discarded
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
rafaeljw committed Oct 18, 2018
1 parent 12b65ea commit f1c8e41
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/cpuidle/governors/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,19 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
* of points is below a threshold. If it is... then use the
* average of these 8 points as the estimated value.
*/
static unsigned int get_typical_interval(struct menu_device *data)
static unsigned int get_typical_interval(struct menu_device *data,
unsigned int predicted_us)
{
int i, divisor;
unsigned int max, thresh, avg;
unsigned int min, max, thresh, avg;
uint64_t sum, variance;

thresh = UINT_MAX; /* Discard outliers above this value */

again:

/* First calculate the average of past intervals */
min = UINT_MAX;
max = 0;
sum = 0;
divisor = 0;
Expand All @@ -217,8 +219,19 @@ static unsigned int get_typical_interval(struct menu_device *data)
divisor++;
if (value > max)
max = value;

if (value < min)
min = value;
}
}

/*
* If the result of the computation is going to be discarded anyway,
* avoid the computation altogether.
*/
if (min >= predicted_us)
return UINT_MAX;

if (divisor == INTERVALS)
avg = sum >> INTERVAL_SHIFT;
else
Expand Down Expand Up @@ -325,7 +338,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
/*
* Use the lowest expected idle interval to pick the idle state.
*/
predicted_us = min(predicted_us, get_typical_interval(data));
predicted_us = min(predicted_us, get_typical_interval(data, predicted_us));

if (tick_nohz_tick_stopped()) {
/*
Expand Down

0 comments on commit f1c8e41

Please sign in to comment.