Author: Dann Corbit
Date: 12:31:25 02/05/02
Go up one level in this thread
On February 05, 2002 at 13:13:09, Miguel A. Ballicora wrote: [snip] >>> register int n=(count+7)/8; >>> >>> switch(count & 7){ >>> case 0: do { *to++ = *from++; >>> case 7: *to++ = *from++; >>> case 6: *to++ = *from++; >>> case 5: *to++ = *from++; >>> case 4: *to++ = *from++; >>> case 3: *to++ = *from++; >>> case 2: *to++ = *from++; >>> case 1: *to++ = *from++; >>> } while(--n > 0); >>> } >>> >> >>Nice -:( >> >>The "do ... while" in the switch statement is really driving me crazy. >> >>Regards, Uli > >I will check K&RII later but IIRC case 0: can be understood as a label >and I just figure that the same will be with "do" >and "while ()" would be the same as "if () goto". >You can jump right into the middle of this loop, crazy isn'it? It's found in the C FAQ: 20.35: What is "Duff's Device"? A: It's a devastatingly deviously unrolled byte-copying loop, devised by Tom Duff while he was at Lucasfilm. In its "classic" form, it looks like: register n = (count + 7) / 8; /* count > 0 assumed */ switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); } where count bytes are to be copied from the array pointed to by from to the memory location pointed to by to (which is a memory- mapped device output register, which is why to isn't incremented). It solves the problem of handling the leftover bytes (when count isn't a multiple of 8) by interleaving a switch statement with the loop which copies bytes 8 at a time. (Believe it or not, it *is* legal to have case labels buried within blocks nested in a switch statement like this. In his announcement of the technique to C's developers and the world, Duff noted that C's switch syntax, in particular its "fall through" behavior, had long been controversial, and that "This code forms some sort of argument in that debate, but I'm not sure whether it's for or against.") From my benchmarking, memcpy() is faster. Duff's device can be worthwhile in a few rare circumstances (e.g. compiler does not know how to unroll and the data objects in the array are large). It can also cause large problems on vector machines (e.g. an enormous slowdown rather than a speedup). For the most part, the day for Duff's device as a useful computing tool are past. All the compilers I use know how to unroll anyway.
This page took 0.01 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.