Ever encountered this one?
It appears all over the place, in particular when you have some algorithm working on vertices, and "Index" is the index of a particular component, i.e. X, Y or Z.
Each time I see this code I feel terribly sorry for the poor guy who wrote it. Especially when I am that guy.
Needless to say (but I'll say it anyway), this code is evil since in this case it includes two hidden divisions by 3. Which is slow.
The usual way to get rid of the modulos is to bite the bullet and write explicit comparisons. For example:
This is a bit better. But not much. Of course, you traded the modulos for comparisons, i.e. you replaced slow divisions with potential branch mispredictions, which are just as evil.
Another popular way to fix this (used in 3DS MAX, for example) is to use a small lookup table:
It almost looks nice. Almost. But of course it suffers from two issues:
- the LUT has to be written to memory each time
- then read back
To get rid of the first issue you usually do:
Hence you just have to read a static LUT. Well, it's also bad. Accessing memory is bad, no matter what. Accessing a static array is even worse, since the corresponding memory can be anywhere, and probably not close to your stack. In short, you replaced slow divisions with even slower cache misses. This is not really a progress.
So, we have the choice between 3 evil ways to do this. Hmmm. Is there any hope left?
Well, maybe. I'd like to propose this alternative:
No modulo, no comparisons, no memory access. Looks good!
In case you donít actually
need all the 3 indices, but only the next one in the sequence, you can use this
alternative function from
Addendum March 22, 2007:
Christer Ericson was kind enough to send two alternative methods. The first one was:
And the most recent one is so simple I think we can just close the topic: