Hello Didier,

 Attached is a new patch to optimize wlsb.c in the current branch.

I suppress the field "is_used" in the c_window structure, and add the fields "count" and "window_mask" in the c_wlsb structure to optimize the code.

Pointers "next" and "oldest" are calculated using the size of the window, minus 1, as mask. No need of modulo.

 I think the code is faster, and more compact.

 Hope you enjoy it ...

 Best regards,

           FWX.

Le 26/05/2012 14:27, Didier Barvaux a écrit :
WBX,

   struct c_window
   {
+       uint16_t is_used;    /**<  Whether the window entry is
used or not */ uint16_t sn;     /**<  The Sequence Number (SN)
associated with the entry (used to acknowledge the entry) */
        uint32_t value;  /**<  The value stored in the window
entry */
-       bool is_used;    /**<  Whether the window entry is used or
not */ };

Why changing the position and the type of is_used?


==> Just to align members of the structure, and compact
     the size (16+16+32) rather than (16+(16)+32+32) when not
compacted.

I see your point. I prefer however to keep the bool type for semantic
reasons.


        size_t bits;
        /// Shift parameter (see 4.5.2 in the RFC 3095)
        rohc_lsb_shift_t p;
+
+       /// @brief The window in which numerous previous values of
the encoded value
+       ///        are stored to help recreate the value
+       struct c_window window[1];
   };

Why not use flexible arrays from ISO C99?


==> Because I am not sure all old compilers understand and support
that, especially older cross-compilers I used. This way is not the
best, but I am sure that it is very easy to compile.

OK. Patch applied on trunk in 2 parts. Thanks for sending it!

See http://bazaar.launchpad.net/~didier-barvaux/rohc/main/revision/354
and http://bazaar.launchpad.net/~didier-barvaux/rohc/main/revision/355
for details.


Regards,
Didier



_______________________________________________
Mailing list: https://launchpad.net/~rohc
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~rohc
More help   : https://help.launchpad.net/ListHelp



=== modified file 'src/common/wlsb.c'
--- src/common/wlsb.c   2012-05-26 12:09:09 +0000
+++ src/common/wlsb.c   2012-06-19 14:57:22 +0000
@@ -43,7 +43,6 @@
        uint16_t sn;     /**< The Sequence Number (SN) associated with the entry
                              (used to acknowledge the entry) */
        uint32_t value;  /**< The value stored in the window entry */
-       bool is_used;    /**< Whether the window entry is used or not */
 };
 
 
@@ -55,11 +54,17 @@
        /// The width of the window
        size_t window_width;
 
+       // The size of the window (power of 2) minus 1
+       size_t window_mask;
+
        /// A pointer on the oldest entry in the window (change on 
acknowledgement)
        size_t oldest;
        /// A pointer on the current entry in the window  (change on add and 
ack)
        size_t next;
 
+       // Count of entries in the window
+       int count;
+
        /// The maximal number of bits for representing the value
        size_t bits;
        /// Shift parameter (see 4.5.2 in the RFC 3095)
@@ -105,10 +110,11 @@
                               const rohc_lsb_shift_t p)
 {
        struct c_wlsb *wlsb;
-       size_t entry;
 
        assert(bits > 0);
        assert(window_width > 0);
+       // window_width must be a power of 2!
+       assert( window_width == 2 || window_width == 4 || window_width == 8 || 
window_width == 16 );
 
        wlsb = malloc(sizeof(struct c_wlsb) + (window_width - 1) * 
sizeof(struct c_window));
        if(wlsb == NULL)
@@ -119,15 +125,12 @@
 
        wlsb->oldest = 0;
        wlsb->next = 0;
+       wlsb->count = 0;
        wlsb->window_width = window_width;
+       wlsb->window_mask = window_width - 1;
        wlsb->bits = bits;
        wlsb->p = p;
 
-       for(entry = 0; entry < window_width; entry++)
-       {
-               wlsb->window[entry].is_used = false;
-       }
-
        return wlsb;
 
 error:
@@ -163,15 +166,18 @@
        assert(wlsb->next < wlsb->window_width);
 
        /* if window is full, an entry is overwritten */
-       if(wlsb->window[wlsb->next].is_used)
-       {
-               wlsb->oldest = (wlsb->oldest + 1) % wlsb->window_width;
+       if(wlsb->count == wlsb->window_width)
+       {
+               wlsb->oldest = (wlsb->oldest + 1) & wlsb->window_mask;
+       }
+       else
+       {
+               ++wlsb->count;
        }
 
        wlsb->window[wlsb->next].sn = sn;
        wlsb->window[wlsb->next].value = value;
-       wlsb->window[wlsb->next].is_used = true;
-       wlsb->next = (wlsb->next + 1) % wlsb->window_width;
+       wlsb->next = (wlsb->next + 1) & wlsb->window_mask;
 }
 
 
@@ -193,31 +199,28 @@
                        size_t *const bits_nr)
 {
        size_t entry;
-       bool is_window_valid;
        uint16_t min;
        uint16_t max;
+       int i;
 
        assert(wlsb != NULL);
        assert(wlsb->window != NULL);
        /* (value <= 0xffff) always ensured because value is of type uint16_t */
        assert(bits_nr != NULL);
 
+       /* If the window contains no value */
+       if(wlsb->count==0)
+       {
+               /* cannot do anything if the window contains no value */
+               goto error;
+       }
+
        min = 0xffff;
        max = 0;
-       is_window_valid = false;
 
        /* find out the interval in which all the values from the window stand 
*/
-       for(entry = 0; entry < wlsb->window_width; entry++)
+       for(i = wlsb->count, entry = wlsb->oldest ; i != 0; i--)
        {
-               /* skip entry if not in use */
-               if(!(wlsb->window[entry].is_used))
-               {
-                       continue;
-               }
-
-               /* the window contains at least one value */
-               is_window_valid = true;
-
                /* change the minimal and maximal values if appropriate */
                if(wlsb->window[entry].value < min)
                {
@@ -227,12 +230,7 @@
                {
                        max = wlsb->window[entry].value;
                }
-       }
-
-       /* cannot do anything if the window contains no value */
-       if(!is_window_valid)
-       {
-               goto error;
+               entry = ( entry + 1 ) & wlsb->window_mask;
        }
 
        /* find the minimal number of bits of the value required to be able
@@ -279,31 +277,27 @@
                        size_t *const bits_nr)
 {
        size_t entry;
-       bool is_window_valid;
        uint32_t min;
        uint32_t max;
+       int i;
 
        assert(wlsb != NULL);
        assert(wlsb->window != NULL);
        assert(value <= 0xffffffff);
        assert(bits_nr != NULL);
 
+       /* cannot do anything if the window contains no value */
+       if(wlsb->count==0)
+       {
+               goto error;
+       }
+
        min = 0xffffffff;
        max = 0;
-       is_window_valid = false;
 
        /* find out the interval in which all the values from the window stand 
*/
-       for(entry = 0; entry < wlsb->window_width; entry++)
+       for(i = wlsb->count, entry = wlsb->oldest ; i != 0; i--)
        {
-               /* skip entry if not in use */
-               if(!(wlsb->window[entry].is_used))
-               {
-                       continue;
-               }
-
-               /* the window contains at least one value */
-               is_window_valid = true;
-
                /* change the minimal and maximal values if appropriate */
                if(wlsb->window[entry].value < min)
                {
@@ -313,12 +307,7 @@
                {
                        max = wlsb->window[entry].value;
                }
-       }
-
-       /* cannot do anything if the window contains no value */
-       if(!is_window_valid)
-       {
-               goto error;
+               entry = ( entry + 1 ) & wlsb->window_mask;
        }
 
        /* find the minimal number of bits of the value required to be able
@@ -357,7 +346,7 @@
  */
 void c_ack_sn_wlsb(struct c_wlsb *s, int sn)
 {
-       int found = 0;
+       size_t entry;
        int i;
 
        /* check the W-LSB object validity */
@@ -368,31 +357,15 @@
 
        /* search for the window entry that matches the given SN
         * starting from the oldest one */
-       for(i = s->oldest; i < s->window_width; i++)
+       for(entry = s->oldest, i = s->count; i != 0; i--)
        {
-               if(s->window[i].is_used && s->window[i].sn == sn)
+               if(s->window[i].sn == sn)
                {
-                       found = 1;
+                       /* remove the window entry if found */
+                       c_ack_remove(s, i);
                        break;
                }
-       }
-
-       if(!found)
-       {
-               for(i = 0; i < s->oldest; i++)
-               {
-                       if(s->window[i].is_used && s->window[i].sn == sn)
-                       {
-                               found = 1;
-                               break;
-                       }
-               }
-       }
-
-       /* remove the window entry if found */
-       if(found)
-       {
-               c_ack_remove(s, i);
+               entry = ( entry + 1 ) & s->window_mask;
        }
 }
 
@@ -407,15 +380,14 @@
  */
 int c_sum_wlsb(struct c_wlsb *s)
 {
+       size_t entry;
+       int sum = 0;
        int i;
-       int sum = 0;
 
-       for(i = 0; i < s->window_width; i++)
+       for(entry = s->oldest, i = s->count; i != 0; i--)
        {
-               if(s->window[i].is_used)
-               {
-                       sum += s->window[i].value;
-               }
+               sum += s->window[entry].value;
+               entry = ( entry + 1 ) & s->window_mask;
        }
 
        return sum;
@@ -432,20 +404,22 @@
  */
 int c_mean_wlsb(struct c_wlsb *s)
 {
+       size_t entry;
+       int sum = 0;
        int i;
-       int sum = 0;
-       int num = 0;
-
-       for(i = 0; i < s->window_width; i++)
-       {
-               if(s->window[i].is_used)
-               {
-                       sum += s->window[i].value;
-                       num++;
-               }
-       }
-
-       return (num > 0 ? sum / num : 0);
+
+       if( s->count == 0 )
+       {
+               return 0;
+       }
+
+       for(entry = s->oldest, i = s->count; i != 0; i--)
+       {
+               sum += s->window[entry].value;
+               entry = ( entry + 1 ) & s->window_mask;
+       }
+
+       return sum / s->count;
 }
 
 
@@ -461,7 +435,8 @@
  */
 static void c_ack_remove(struct c_wlsb *s, int index)
 {
-       int j;
+        size_t entry;
+       int i;
 
        /* check the W-LSB object validity */
        if(s == NULL)
@@ -471,75 +446,16 @@
 
        rohc_debugf(2, "index is %d\n", index);
 
-       if(s->oldest == index)
-       {
-               /* remove only the oldest entry */
-               s->window[s->oldest].is_used = false;
-       }
-       else if(s->oldest < index)
-       {
-               /* remove all entries from oldest to (not including) index */
-               for(j = s->oldest; j < index; j++)
-               {
-                       s->window[j].is_used = false;
-               }
-       }
-       else /* s->oldest > index */
-       {
-               /* remove all entries from oldest to wrap-around and all from 
start
-                * to (excluding) index */
-               for(j = s->oldest; j < s->window_width; j++)
-               {
-                       s->window[j].is_used = false;
-               }
-               for(j = 0; j < index; j++)
-               {
-                       s->window[j].is_used = false;
-               }
-       }
-
-       /* fix the s->oldest pointer */
-       if(index >= (s->window_width - 1))
-       {
-               s->oldest = 0;
-       }
-       else
-       {
-               s->oldest = index;
-               if(s->oldest >= s->window_width)
-               {
-                       s->oldest = 0;
-               }
-       }
-
-       /* fix the s->next pointer */
-       s->next = s->oldest;
-       for(j = s->oldest; j < s->window_width; j++)
-       {
-               if(s->window[j].is_used)
-               {
-                       s->next = (s->next + 1) % s->window_width;
-               }
-               else
-               {
-                       break;
-               }
-       }
-       for(j = 0; j < s->oldest; j++)
-       {
-               if(s->window[j].is_used)
-               {
-                       s->next = (s->next + 1) % s->window_width;
-               }
-               else
-               {
-                       break;
-               }
-       }
-
-       if(s->oldest >= s->window_width)
-       {
-               s->oldest = 0;
+       for( entry = s->oldest, i = s->count; i != 0 ; i-- )
+       {
+               /* remove this oldest entry */
+               --s->count;
+               s->oldest = ( entry + 1 ) & s->window_mask;
+               if( entry == index )
+               {
+                       break;
+               }
+               entry = s->oldest;
        }
 }
 

_______________________________________________
Mailing list: https://launchpad.net/~rohc
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~rohc
More help   : https://help.launchpad.net/ListHelp

Reply via email to