From: Johannes Berg Date: Sat, 13 Apr 2013 22:00:16 +0000 (+0200) Subject: backports: average: backport efficiency improvements X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=fe9c900a60af687192c01d8f9df9de828e4f6fd7;p=openwrt%2Fstaging%2Fblogic.git backports: average: backport efficiency improvements This is what we get for not copying it directly :-) For now, backport af556884359 manually. Signed-off-by: Johannes Berg --- diff --git a/backport/compat/average.c b/backport/compat/average.c index 37cbfd6bdc7e..b7a51a1fcccd 100644 --- a/backport/compat/average.c +++ b/backport/compat/average.c @@ -11,23 +11,27 @@ #include #include #include +#include /** * ewma_init() - Initialize EWMA parameters * @avg: Average structure * @factor: Factor to use for the scaled up internal value. The maximum value - * of averages can be ULONG_MAX/(factor*weight). + * of averages can be ULONG_MAX/(factor*weight). For performance reasons + * factor has to be a power of 2. * @weight: Exponential weight, or decay rate. This defines how fast the - * influence of older values decreases. Has to be bigger than 1. + * influence of older values decreases. For performance reasons weight has + * to be a power of 2. * * Initialize the EWMA parameters for a given struct ewma @avg. */ void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight) { - WARN_ON(weight <= 1 || factor == 0); + WARN_ON(!is_power_of_2(weight) || !is_power_of_2(factor)); + + avg->weight = ilog2(weight); + avg->factor = ilog2(factor); avg->internal = 0; - avg->weight = weight; - avg->factor = factor; } EXPORT_SYMBOL_GPL(ewma_init); @@ -41,9 +45,9 @@ EXPORT_SYMBOL_GPL(ewma_init); struct ewma *ewma_add(struct ewma *avg, unsigned long val) { avg->internal = avg->internal ? - (((avg->internal * (avg->weight - 1)) + - (val * avg->factor)) / avg->weight) : - (val * avg->factor); + (((avg->internal << avg->weight) - avg->internal) + + (val << avg->factor)) >> avg->weight : + (val << avg->factor); return avg; } EXPORT_SYMBOL_GPL(ewma_add); diff --git a/backport/include/linux/average.h b/backport/include/linux/average.h index 16eff0da3b7f..2d6210e53105 100644 --- a/backport/include/linux/average.h +++ b/backport/include/linux/average.h @@ -29,6 +29,6 @@ extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); */ static inline unsigned long ewma_read(const struct ewma *avg) { - return DIV_ROUND_CLOSEST(avg->internal, avg->factor); + return avg->internal >> avg->factor; } #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) */