From: Rasmus Villemoes Date: Tue, 16 Feb 2016 19:19:19 +0000 (+0100) Subject: cpuidle: menu: help gcc generate slightly better code X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=3b99669b75db04e411bb298591224a9e8e4f57fb;p=openwrt%2Fstaging%2Fblogic.git cpuidle: menu: help gcc generate slightly better code We know that the avg variable actually ends up holding a 32 bit quantity, since it's an average of such numbers. It is only a u64 because it is temporarily used to hold the sum. Making it an actual u32 allows gcc to generate slightly better code, e.g. when computing the square, it can do a 32x32->64 multiply. Signed-off-by: Rasmus Villemoes Signed-off-by: Rafael J. Wysocki --- diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index beef7ae123ba..27fc733cb5b9 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -199,8 +199,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); static void get_typical_interval(struct menu_device *data) { int i, divisor; - unsigned int max, thresh; - uint64_t avg, variance; + unsigned int max, thresh, avg; + uint64_t sum, variance; thresh = UINT_MAX; /* Discard outliers above this value */ @@ -208,28 +208,28 @@ again: /* First calculate the average of past intervals */ max = 0; - avg = 0; + sum = 0; divisor = 0; for (i = 0; i < INTERVALS; i++) { unsigned int value = data->intervals[i]; if (value <= thresh) { - avg += value; + sum += value; divisor++; if (value > max) max = value; } } if (divisor == INTERVALS) - avg >>= INTERVAL_SHIFT; + avg = sum >> INTERVAL_SHIFT; else - do_div(avg, divisor); + avg = div_u64(sum, divisor); /* Then try to determine variance */ variance = 0; for (i = 0; i < INTERVALS; i++) { unsigned int value = data->intervals[i]; if (value <= thresh) { - int64_t diff = value - avg; + int64_t diff = (int64_t)value - avg; variance += diff * diff; } } @@ -251,7 +251,7 @@ again: * Use this result only if there is no timer to wake us up sooner. */ if (likely(variance <= U64_MAX/36)) { - if (((avg*avg > variance*36) && (divisor * 4 >= INTERVALS * 3)) + if ((((u64)avg*avg > variance*36) && (divisor * 4 >= INTERVALS * 3)) || variance <= 400) { if (data->next_timer_us > avg) data->predicted_us = avg;