Click
Loading...
Searching...
No Matches
ewma.hh
Go to the documentation of this file.
1#ifndef CLICK_EWMA_HH
2#define CLICK_EWMA_HH
3#include <click/glue.hh>
4#include <click/confparse.hh>
5CLICK_DECLS
6
7template <unsigned alpha, unsigned shift>
8class EXPSMOOTH {
9 public:
10 unsigned val;
11
12 void update(unsigned obs) {
13 val = (obs * alpha + ((1 << shift) - alpha) * obs) >> shift;
14 }
15
16
17 unsigned unscaled_average() const {
18 return val;
19 }
20
21 unsigned average() const {
22 return val;
23 }
24};
25
92template <typename P>
93class DirectEWMAX : public P { public:
94
95 typedef typename P::value_type value_type;
96
99 : _avg(0) {
100 }
101
103 DirectEWMAX(value_type scaled_value)
104 : _avg(scaled_value) {
105 }
106
109 value_type scaled_average() const {
110 return _avg;
111 }
112
115 value_type unscaled_average() const {
116 return (_avg + (P::scaled_one() >> 1)) >> P::scale();
117 }
118
120 void clear() {
121 _avg = 0;
122 }
123
125 inline void assign(value_type scaled_value) {
126 _avg = scaled_value;
127 }
128
131 inline void update(value_type x);
132
138 void update_n(value_type x, unsigned n);
139
143 String unparse() const;
144
148 inline void update_with(value_type x) CLICK_DEPRECATED;
149
150 private:
151
152 value_type _avg;
153
154};
155
156template <typename P>
157inline void
159{
160 value_type x_scaled = (x << P::scale()) + P::compensation();
161 unsigned stability = P::stability_shift();
162#if HAVE_ARITHMETIC_RIGHT_SHIFT
163 _avg += static_cast<typename P::signed_value_type>(x_scaled - _avg) >> stability;
164#else
165 if (x_scaled < _avg)
166 _avg -= (_avg - x_scaled) >> stability;
167 else
168 _avg += (x_scaled - _avg) >> stability;
169#endif
170}
171
172template <typename P>
173void
174DirectEWMAX<P>::update_n(value_type x, unsigned n)
175{
176 // XXX use table lookup
177 value_type x_scaled = x << P::scale();
178 if (n >= 100)
179 _avg = x_scaled;
180 else {
181 x_scaled += P::compensation();
182 unsigned stability = P::stability_shift();
183#if HAVE_ARITHMETIC_RIGHT_SHIFT
184 for (; n > 0; n--)
185 _avg += static_cast<typename P::signed_value_type>(x_scaled - _avg) >> stability;
186#else
187 if (x_scaled < _avg)
188 for (; n > 0; n--)
189 _avg -= (_avg - x_scaled) >> stability;
190 else
191 for (; n > 0; n--)
192 _avg += (x_scaled - _avg) >> stability;
193#endif
194 }
195}
196
197template <typename P>
198inline String
200{
201 return cp_unparse_real2(scaled_average(), P::scale());
202}
203
204template <typename P>
205inline void
207{
208 update(x);
209}
210
231template <unsigned STABILITY, unsigned SCALE, typename T = unsigned, typename U = int>
232class FixedEWMAXParameters { public:
233
234 typedef T value_type;
235 typedef U signed_value_type;
236
239 static unsigned stability_shift() {
240 return STABILITY;
241 }
242
245 static unsigned scale() {
246 static_assert(SCALE < sizeof(T) * 8, "SCALE too big for EWMA type.");
247 return SCALE;
248 }
249
251 static value_type scaled_one() {
252 return (value_type) 1 << SCALE;
253 }
254
257 static unsigned compensation() {
258 return 1 << (STABILITY - 1);
259 }
260
261};
262
266
270
271
289template <unsigned SCALE, typename T = unsigned, typename U = int>
291
292 typedef T value_type;
293 typedef U signed_value_type;
294
297 : _stability(4) {
298 }
299
303 unsigned stability_shift() const {
304 return _stability;
305 }
306
310 _stability = stability_shift;
311 }
312
315 static unsigned scale() {
316 return SCALE;
317 }
318
320 static value_type scaled_one() {
321 return (value_type) 1 << SCALE;
322 }
323
326 unsigned compensation() const {
327 return 1 << (stability_shift() - 1);
328 }
329
330 private:
331
332 unsigned _stability;
333
334};
335
336
337
391template <typename P>
392class RateEWMAX : public P { public:
393
394 typedef typename P::value_type value_type;
395 typedef typename P::signed_value_type signed_value_type;
396
399 _current_epoch = P::epoch();
400 for (unsigned i = 0; i < P::rate_count; i++)
401 _current[i] = 0;
402 }
403
411 signed_value_type scaled_average(unsigned ratenum = 0) const {
412 // note: return type must be signed!
413 return _avg[ratenum].scaled_average();
414 }
415
418 unsigned scale(unsigned ratenum = 0) const {
419 return _avg[ratenum].scale();
420 }
421
429 inline int rate(unsigned ratenum = 0) const;
430
439 inline void update(signed_value_type delta, unsigned ratenum = 0);
440
449 String unparse_rate(unsigned ratenum = 0) const;
450
451 private:
452
453 unsigned _current_epoch;
454 value_type _current[P::rate_count];
455 DirectEWMAX<P> _avg[P::rate_count];
456
457 inline void update_time(unsigned now);
458
459};
460
474template <unsigned STABILITY, unsigned SCALE, typename T = unsigned, typename U = int>
475class RateEWMAXParameters : public FixedEWMAXParameters<STABILITY, SCALE, T, U> { public:
476 enum {
477 rate_count = 1
478 };
479
482 static unsigned epoch() {
483 return click_jiffies();
484 }
485
487 static unsigned epoch_frequency() {
488 return CLICK_HZ;
489 }
490};
491
496
497
498template <typename P>
499inline void
500RateEWMAX<P>::update_time(unsigned now)
501{
502 unsigned jj = _current_epoch;
503 if (now != jj) {
504 for (unsigned i = 0; i < P::rate_count; i++) {
505 // adjust the average rate using the last measured packets
506 _avg[i].update(_current[i]);
507
508 // adjust for time w/ no packets
509 if (jj + 1 != now)
510 _avg[i].update_n(0, now - jj - 1);
511 _current[i] = 0;
512 }
513 _current_epoch = now;
514 }
515}
516
517template <typename P>
518inline void
519RateEWMAX<P>::update(signed_value_type delta, unsigned ratenum)
520{
521 update_time(P::epoch());
522 _current[ratenum] += delta;
523}
524
525template <typename P>
526inline int
527RateEWMAX<P>::rate(unsigned ratenum) const
528{
529 return (scaled_average(ratenum) * P::epoch_frequency()) >> _avg[ratenum].scale();
530}
531
532template <typename P>
533inline String
534RateEWMAX<P>::unparse_rate(unsigned ratenum) const
535{
536 return cp_unparse_real2(scaled_average(ratenum) * P::epoch_frequency(), _avg[ratenum].scale());
537}
538
539CLICK_ENDDECLS
540#endif
An exponentially weighted moving average.
Definition ewma.hh:93
String unparse() const
Unparse the current average into a String.
Definition ewma.hh:199
void assign(value_type scaled_value)
Assign the EWMA to scaled average scaled_value.
Definition ewma.hh:125
void clear()
Reset the EWMA to value 0.
Definition ewma.hh:120
void update(value_type x)
Update the moving average with a new observation.
Definition ewma.hh:158
value_type scaled_average() const
Return the current scaled moving average.
Definition ewma.hh:109
void update_n(value_type x, unsigned n)
Update the moving average with n identical observations.
Definition ewma.hh:174
void update_with(value_type x)
Update the moving average with a new observation (deprecated).
Definition ewma.hh:206
DirectEWMAX(value_type scaled_value)
Construct a EWMA with initial scaled average scaled_value.
Definition ewma.hh:103
DirectEWMAX()
Construct a EWMA with initial average 0.
Definition ewma.hh:98
value_type unscaled_average() const
Return the current moving average, rounded up.
Definition ewma.hh:115
Parameters for a EWMA with constant scaling factor and stability shift.
Definition ewma.hh:232
static value_type scaled_one()
Return this EWMA's scaled value for one.
Definition ewma.hh:251
static unsigned stability_shift()
Return this EWMA's stability shift.
Definition ewma.hh:239
static unsigned scale()
Return this EWMA's scaling factor (bits of fraction).
Definition ewma.hh:245
static unsigned compensation()
Return this EWMA's compensation.
Definition ewma.hh:257
An exponentially weighted moving average used to measure a rate.
Definition ewma.hh:392
RateEWMAX()
Create a rate EWMA with initial value(s) 0.
Definition ewma.hh:398
int rate(unsigned ratenum=0) const
Return the current rate in samples per second.
Definition ewma.hh:527
void update(signed_value_type delta, unsigned ratenum=0)
Update the sample count for the current epoch.
Definition ewma.hh:519
signed_value_type scaled_average(unsigned ratenum=0) const
Return the current scaled moving average.
Definition ewma.hh:411
unsigned scale(unsigned ratenum=0) const
Returns one of the average's scaling factors (bits of fraction).
Definition ewma.hh:418
String unparse_rate(unsigned ratenum=0) const
Unparse the current average into a String.
Definition ewma.hh:534
Parameters for a RateEWMA with constant scaling factor and alpha, one rate count, and epochs of jiffi...
Definition ewma.hh:475
static unsigned epoch()
Return the current epoch number.
Definition ewma.hh:482
static unsigned epoch_frequency()
Return the number of epochs (jiffies) per second.
Definition ewma.hh:487
Parameters for a EWMA with constant scaling factor and user-settable alpha.
Definition ewma.hh:290
static value_type scaled_one()
Return this EWMA's scaled value for one.
Definition ewma.hh:320
void set_stability_shift(unsigned stability_shift)
Set the current stability shift.
Definition ewma.hh:309
unsigned compensation() const
Return this EWMA's compensation.
Definition ewma.hh:326
static unsigned scale()
Return this EWMA's scaling factor (bits of fraction).
Definition ewma.hh:315
unsigned stability_shift() const
Return the current stability shift.
Definition ewma.hh:303
StabilityEWMAXParameters()
Construct a StabilityEWMAXParameters with initial alpha 1/16.
Definition ewma.hh:296
A string of characters.
Definition string.hh:22
Support for parsing configuration strings.
DirectEWMAX< FixedEWMAXParameters< 3, 10 > > FastDirectEWMA
A DirectEWMAX with stability shift 3 (alpha 1/8), scaling factor 10 (10 bits of fraction),...
Definition ewma.hh:269
RateEWMAX< RateEWMAXParameters< 4, 10, uint64_t, int64_t > > RateEWMA
A RateEWMAX with stability shift 4 (alpha 1/16), scaling factor 10 (10 bits of fraction),...
Definition ewma.hh:495
DirectEWMAX< FixedEWMAXParameters< 4, 10 > > DirectEWMA
A DirectEWMAX with stability shift 4 (alpha 1/16), scaling factor 10 (10 bits of fraction),...
Definition ewma.hh:265