[Vorbis-dev] tremor: macro-ize mask[] table

Adam D. Moss adam at gimp.org
Sun Nov 21 06:03:30 PST 2004


Hi!

This little patch turns bitwise.c's mask[]
lookup table into a bit-twiddling macro (which avoids
the <<32 case without branching).  This
spares the size of the 132-byte lookup table (and
then a bit more, curiously).

While I expected this to generally be faster
(because it uses a few more instructions in place of
a table lookup), it's actually slightly slower
than the LUT, in a tight benchmark (perhaps because
of the large chance of the LUT being in the dcache?),
on an i32-athlon-classic at least.  But other
architectures may see some small benefit -- or
this could be of academic interest to someone. :)

It's been _V_BIT_TEST'd on i32, and I expect it to
work on 64-bit archs but haven't been able to test.

--Adam
-------------- next part --------------
Index: .libs/libvorbisidec.a
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: bitwise.c
===================================================================
--- bitwise.c	(revision 3086)
+++ bitwise.c	(working copy)
@@ -23,14 +23,8 @@
 #include "misc.h"
 #include "ogg.h"
 
-static unsigned long mask[]=
-{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
- 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
- 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
- 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
- 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
- 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
- 0x3fffffff,0x7fffffff,0xffffffff };
+#define MASK(b) ( (unsigned long)( (( (1<<((b)&31)) ^ (((b)&32)>>5) ) ) -1 ) \
+                  & 0xffffffff )
 
 /* spans forward, skipping as many bytes as headend is negative; if
    headend is zero, simply finds next byte.  If we're up to the end
@@ -80,7 +74,7 @@
 
 /* Read in bits without advancing the bitptr; bits <= 32 */
 long oggpack_look(oggpack_buffer *b,int bits){
-  unsigned long m=mask[bits];
+  unsigned long m=MASK(bits);
   unsigned long ret;
 
   bits+=b->headbit;
@@ -229,15 +223,15 @@
     int tbit=bits?bits:ilog(b[i]);
     if((test=oggpack_look(&r,tbit))==0xffffffff)
       report("out of data!\n");
-    if(test!=(b[i]&mask[tbit])){
-      fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
+    if(test!=(b[i]&MASK(tbit))){
+      fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&MASK(tbit)),test);
       report("looked at incorrect value!\n");
     }
     if((test=oggpack_read(&r,tbit))==0xffffffff){
       report("premature end of data when reading!\n");
     }
-    if(test!=(b[i]&mask[tbit])){
-      fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
+    if(test!=(b[i]&MASK(tbit))){
+      fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&MASK(tbit)),test);
       report("read incorrect value!\n");
     }
     bitcount+=tbit;
@@ -607,10 +601,10 @@
                     j-begin,ilen);
             exit(1);
           }
-          if(temp!=(values[j]&mask[len[j]])){
+          if(temp!=(values[j]&MASK(len[j]))){
             fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
 ,
-                    values[j]&mask[len[j]],temp,j-begin,len[j]);
+                    values[j]&MASK(len[j]),temp,j-begin,len[j]);
             exit(1);
           }
           bitcount+=len[j];
@@ -642,10 +636,10 @@
                     j-begin);
             exit(1);
           }
-          if(temp!=(values[j]&mask[len[j]])){
+          if(temp!=(values[j]&MASK(len[j]))){
             fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
 ,
-                    values[j]&mask[len[j]],temp,j-begin,len[j]);
+                    values[j]&MASK(len[j]),temp,j-begin,len[j]);
             exit(1);
           }
 	  oggpack_adv(&o,len[j]);


More information about the Vorbis-dev mailing list