C Duff's device is a loop unrolling technique that combines a switch statement inside a while loop, allowing the loop condition and case labels to interact. It eliminates loop overhead by processing multiple iterations per loop cycle, originally invented for fast memory copying.
Use Duff's device when loop overhead matters and you need to process arrays in bulk without conditional branching.
This example demonstrates Duff's device for efficient array copying.
// compile: gcc -O2 -o duffs duffs.c // run: ./duffs // description: loop unrolling with Duff's device #include <stdio.h> #include <string.h> #include <time.h> // Naive loop: one element per iteration void copy_simple(int *dst, const int *src, int n) { for (int i = 0; i < n; i++) { dst[i] = src[i]; } } // Duff's device: 8 elements per loop cycle void copy_duffs(int *dst, const int *src, int n) { int count = (n + 7) / 8; // round up to nearest multiple of 8 switch (n % 8) { case 0: do { *dst++ = *src++; case 7: *dst++ = *src++; case 6: *dst++ = *src++; case 5: *dst++ = *src++; case 4: *dst++ = *src++; case 3: *dst++ = *src++; case 2: *dst++ = *src++; case 1: *dst++ = *src++; } while (--count > 0); } } int main() { int src[1000], dst[1000]; // Initialize source for (int i = 0; i < 1000; i++) { src[i] = i; } // Test correctness copy_duffs(dst, src, 1000); printf("Copy successful: dst[500] = %d\n", dst[500]); // Benchmark (simple version) clock_t start = clock(); for (int iter = 0; iter < 1000; iter++) { copy_simple(dst, src, 1000); } clock_t simple_time = clock() - start; // Benchmark (Duff's device) start = clock(); for (int iter = 0; iter < 1000; iter++) { copy_duffs(dst, src, 1000); } clock_t duffs_time = clock() - start; printf("Simple: %ld cycles\n", simple_time); printf("Duffs: %ld cycles\n", duffs_time); printf("Speedup: %.2fx\n", (double)simple_time / duffs_time); return 0; }
Loop unrolling principle:
-O2 or -O3Why Duff's device is confusing:
switch inside do-while is unusualswitch case labels are jumped to on first iterationModern alternatives:
Practical uses (rare today):
Correctness caveats:
count = (n + 7) / 8 for rounding upPerformance notes:
-O3Readability trade-off: