From: Bruno Randolf <br1@einfach.org>
To: linville@tuxdriver.com
Cc: randy.dunlap@oracle.com, br1@thinktube.com, peterz@infradead.org,
blp@cs.stanford.edu, linux-wireless@vger.kernel.org,
linux-kernel@vger.kernel.org, Lars_Ericsson@telia.com, j@w1.fi,
stefanr@s5r6.in-berlin.de, kosaki.motohiro@jp.fujitsu.com,
akpm@linux-foundation.org, kevin.granade@gmail.com,
johannes@sipsolutions.net
Subject: [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts
Date: Thu, 02 Dec 2010 19:12:36 +0900 [thread overview]
Message-ID: <20101202101236.22988.1691.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20101202101231.22988.33396.stgit@localhost6.localdomain6>
Using bitshifts instead of division and multiplication should improve
performance. That requires weight and factor to be powers of two, but i think
this is something we can live with.
Thanks to Peter Zijlstra for the improved formula!
Signed-off-by: Bruno Randolf <br1@einfach.org>
---
include/linux/average.h | 4 +---
lib/average.c | 29 +++++++++++++++++++++--------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/include/linux/average.h b/include/linux/average.h
index 7706e40..c6028fd 100644
--- a/include/linux/average.h
+++ b/include/linux/average.h
@@ -1,8 +1,6 @@
#ifndef _LINUX_AVERAGE_H
#define _LINUX_AVERAGE_H
-#include <linux/kernel.h>
-
/* Exponentially weighted moving average (EWMA) */
/* For more documentation see lib/average.c */
@@ -26,7 +24,7 @@ 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_AVERAGE_H */
diff --git a/lib/average.c b/lib/average.c
index f1d1b46..f438b40 100644
--- a/lib/average.c
+++ b/lib/average.c
@@ -24,18 +24,31 @@
* 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);
+ int n;
+
+ /* get bitshift for weight */
+ for (n = 0; !(weight & 1); n++)
+ weight = weight >> 1;
+ WARN_ON(weight > 1 || n < 1);
+ avg->weight = n;
+
+ /* get bitshift for factor */
+ for (n = 0; !(factor & 1); n++)
+ factor = factor >> 1;
+ WARN_ON(factor > 1);
+ avg->factor = n;
+
avg->internal = 0;
- avg->weight = weight;
- avg->factor = factor;
}
EXPORT_SYMBOL(ewma_init);
@@ -49,9 +62,9 @@ EXPORT_SYMBOL(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(ewma_add);
next prev parent reply other threads:[~2010-12-02 10:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-02 10:12 [PATCH 1/3] ath5k: Use EWMA factor of 1024 instead of 1000 Bruno Randolf
2010-12-02 10:12 ` Bruno Randolf [this message]
2010-12-02 10:20 ` [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts Johannes Berg
2010-12-02 10:37 ` Bruno Randolf
2010-12-02 10:12 ` [PATCH 3/3] nl80211/mac80211: Report signal average Bruno Randolf
2010-12-07 19:06 ` John W. Linville
2010-12-07 19:17 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101202101236.22988.1691.stgit@localhost6.localdomain6 \
--to=br1@einfach.org \
--cc=Lars_Ericsson@telia.com \
--cc=akpm@linux-foundation.org \
--cc=blp@cs.stanford.edu \
--cc=br1@thinktube.com \
--cc=j@w1.fi \
--cc=johannes@sipsolutions.net \
--cc=kevin.granade@gmail.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=peterz@infradead.org \
--cc=randy.dunlap@oracle.com \
--cc=stefanr@s5r6.in-berlin.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.