Skip to content

Instantly share code, notes, and snippets.

@ggandor
Created May 25, 2021 10:49
Show Gist options
  • Save ggandor/bc659175094c333dced65e9c76d066fc to your computer and use it in GitHub Desktop.
Save ggandor/bc659175094c333dced65e9c76d066fc to your computer and use it in GitHub Desktop.
// Tom Duff, 1983 (trivia: for a Lucasfilm animation)
// problem: loop unrolling (reducing the #of loop tests by putting multiple copies of the
// given instruction into the body, instead of just one)
// implementation problem: given x-fold unrolling, performing the remainder of iterations,
// when count (#of original cycles) is not divisible by x
send(to, from, count)
register short *to, *from;
register count;
{
register n = (count + 7) / 8;
switch (count % 8) {
case 0: do {
*to = *from++; // labels 1-7 _inside_ the loop, ie. jumping right into the middle
case 7: *to = *from++; // without `break`, each fall through, till the end
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); // still inside the _switch statement_, so the loop runs its course
// (now with full cycles) *
}
}
// * remember, a C `switch` is nothing more than a `goto`: control jumps to
// the statement after the matching label, and then all the rest of the code in
// the block executes (if no `break`)
// Caveat: this is mostly just clever and fun code magic, but performance-wise
// a very-very "it depends" kind of trick, often counterproductive, should be
// considered in rare cases only, if you really know what you're doing
// (https://en.wikipedia.org/wiki/Duff's_device#Performance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment