From: jlnance@eos.ncsu.edu (JAMES LEWIS NANCE)
Subject: Duff's Device
Originator: jlnance@c00005-118dan.eos.ncsu.edu
Reply-To: jlnance@eos.ncsu.edu (JAMES LEWIS NANCE)
Organization: North Carolina State University, Project Eos
Date: Tue, 15 Sep 1992 14:43:04 GMT


I read the post about Duffs device yesterday, and had to try it out.  I found,
much to my supprise, that Duffs device slowed my program down, instead of
speeding it up.  W/O Duff it takes 23 Seconds to run and W/ Duff it takes 27
seconds to run.  This is especially discouraging since I only Duffed one of the
critical loops and left the others alone.  This means that the real slowdown is
much greater than the 23/27 that it would appear to be.  Does this slowdown make
sence or have I done something stupid.  I have included my code below.  Note
that my array addresses are supposed to be from 1-n and not form 0-(n-1).

Non Duff:
#define Dot(a, b, n, r)  {                                                 \
                         double *Ai = (a)+(n)+1;                           \
                         double *Bi = (b)+(n);                             \
                         r          = 0;                                   \
                         while(--Ai>(a)) r += *Ai * *Bi--;                 \
                         }


Duff:
#define Dot(a, b, n, r)  {                                                 \
                         double *Ai = (a)+(n);                             \
                         double *Bi = (b)+(n);                             \
                         r          = 0.0;                                 \
                         switch(n & 0x0f) {                                \
                              case  0: do {  r += *Ai-- * *Bi--;           \
                              case 15:       r += *Ai-- * *Bi--;           \
                              case 14:       r += *Ai-- * *Bi--;           \
                              case 13:       r += *Ai-- * *Bi--;           \
                              case 12:       r += *Ai-- * *Bi--;           \
                              case 11:       r += *Ai-- * *Bi--;           \
                              case 10:       r += *Ai-- * *Bi--;           \
                              case  9:       r += *Ai-- * *Bi--;           \
                              case  8:       r += *Ai-- * *Bi--;           \
                              case  7:       r += *Ai-- * *Bi--;           \
                              case  6:       r += *Ai-- * *Bi--;           \
                              case  5:       r += *Ai-- * *Bi--;           \
                              case  4:       r += *Ai-- * *Bi--;           \
                              case  3:       r += *Ai-- * *Bi--;           \
                              case  2:       r += *Ai-- * *Bi--;           \
                              case  1:       r += *Ai-- * *Bi--;           \
                                   } while(Ai>a);                          \
                              }                                            \
                         }

Note that the slowdown was approximatly the same if I used 8 instead of 16
statements inside my loop.  The times listed above were on a DECstation 2100,
and were compiled with cc -O.  Something else that supprised me is that lint
does not complain about this construct.  I would have expected a warning about
a loop not entered at the top, but I dont get one.

Jim Nance
Newsgroups: comp.lang.c