Re: [PATCH 24/25]: Macro for moving average

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/2/07, Ian McDonald <ian.mcdonald@xxxxxxxxxxx> wrote:
On 4/2/07, Gerrit Renker <gerrit@xxxxxxxxxxxxxx> wrote:
> Quoting Ian McDonald:
> |  > +/**
> |  > + * Macro for exponentially weighted moving average
> |  > + * @weight: Weight to be used as damping factor, in units of 1/10
> |  > + * Beware that @val is evaluated multiple times.
> |  > + */
> |  > +#define TFRC_EWMA(val, newval, weight) \
> |  > + val = val? ((weight) * val + (10 - (weight)) * (newval)) / 10 : (newval)
> |  > +
> |  Just wondering why you pass weight when you only use 9 anyway and it
> |  just adds a step. Is it used in following patches with a different
> |  weight?
> |
> In the following patches it is used one more time, which is for the `Preventing
> Oscillations' changeset (this is not in the next patch set but in the one after that);
> here again the weight 9/10 is used. I think it is useful to keep the `weight' argument,
> since RFC 3448 suggests to use a different weight for the RTT sample when the `Oscillation
> Prevention' e.g. is not deployed (a q close to zero).
> I think it is better to keep the weight argument, it allows changing the code later, while
> still providing the abstraction: for CCID 3 there are 4 uses of this macro alone.
>
OK.

Acked-by: Ian McDonald <ian.mcdonald@xxxxxxxxxxx>

I don't like macros that receive as a parameter something that will be
changed, its more readable to have it as a inline function and return
the new value, even if the resulting code uses more characters, so I'm
applying the attached patch and will take care of the fallout, that is
small from what I grepped at the_whole_lot.

- Arnaldo
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 9474331..428aa92 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -183,7 +183,7 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
 {
 	const u16 old_s = hctx->ccid3hctx_s;
 
-	hctx->ccid3hctx_s = old_s == 0 ? len : (9 * old_s + len) / 10;
+	hctx->ccid3hctx_s = tfrc_ewma(hctx->ccid3hctx_s, len, 9);
 
 	if (hctx->ccid3hctx_s != old_s)
 		ccid3_update_send_interval(hctx);
@@ -474,8 +474,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 	 *
 	 * q is a constant, RFC 3448 recommends 0.9
 	 */
-	hctx->ccid3hctx_rtt = hctx->ccid3hctx_rtt == 0 ?  r_sample
-			    : (9 * hctx->ccid3hctx_rtt + r_sample) / 10;
+	hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
 
 	/*
 	 * Update allowed sending rate as per draft rfc3448bis, 4.2/4.3
@@ -724,8 +723,7 @@ static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
 	if (unlikely(len == 0))	/* don't update on empty packets (e.g. ACKs) */
 		ccid3_pr_debug("Packet payload length is 0 - not updating\n");
 	else
-		hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
-				    (9 * hcrx->ccid3hcrx_s + len) / 10;
+		hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, len, 9);
 }
 
 static void ccid3_hc_rx_send_feedback(struct sock *sk)
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index faf5f7e..f26e9e9 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -37,6 +37,17 @@ static inline u32 scaled_div32(u64 a, u32 b)
 	return result;
 }
 
+/**
+ * Exponentially weighted moving average
+ * @weight: Weight to be used as damping factor, in units of 1/10
+ */
+static inline u32 tfrc_ewma(const u32 val, const u32 newval, const u8 weight)
+{
+	if (val != 0)
+		return (weight * val + (10 - weight) * newval) / 10; 
+	return newval;
+}
+
 extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
 extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
 

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux