Duff's device

  • 24th Aug 2017
  • 2 min read
  • Tags: 
  • C

"This code forms some sort of argument (...), but I'm not sure whether it's for or against."

send(to, from, count)
register short *to, *from;
register count;
{
	register n = (count + 7) / 8;
	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);
	}
}

Here we have it, the Duff's device in all its beauty. Invented by Tom Duff in 1983, it is a creative way of loop unrolling by interleaving the do while loop with a switch.  Surprisingly the code is a perfectly valid C.

What does it do?

The code copies data from an array containing count of shorts (from) into a memory-mapped output register, represented by a pointer (to).

How does it work?

Let's take the step-by-step approach here. Assume we want to copy 20 bytes of data (count = 20). In the first pass, n would have the value of 3 -- calculated as (20 + 7) / 8 -- and count % 8 would evaluate to 4.

The code behaves like a classic switch now, skipping cases 0, 7, 6 and 5 and jumping to case 4. As there are no breaks, the execution falls through to each successive statement, copying four items in total, and reaches the while.

From this point on, the switch is not evaluated anymore and the code acts like a do while loop -- n is decremented and equals 2, and we jump back to the beginning of do.  The subsequent iterations will always copy eight items from the from array, until we run out of data (n == 0).

The most surprising part of the code is realizing that it is possible to jump into the middle of the do while loop.