Created
May 25, 2021 10:49
-
-
Save ggandor/bc659175094c333dced65e9c76d066fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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