Origin of Quake3's Fast InvSqrt()
geo writes "Beyond3D.com's Ryszard Sommefeldt dons his seersucker hunting jacket and meerschaum pipe to take on his secret identity as graphics code sleuth extraordinaire. In today's thrilling installment, the origins of one of the more famous snippets of graphics code in recent years is under the microscope — Quake3's Fast InvSqrt(), which has been known to cause strong geeks to go wobbly in the knees while contemplating its simple beauty and power." From the article: ""
Can someone enlighten me?
-dave
http://millionnumbers.com/ - own the number of your dreams
Here's a more interesting question: "How does this function compute 1/x^(1/2)?" ;)
I'm asking, because I have no idea how it works.
HAKMEM is classic bathroom reading for hackers. If you want to do it up old-school, print a copy from original scans, double-sided.
Holy crap--you forgot the link but the mods followed your instructions anyway.
Mods: I want +5, Funny for this. No, no, wait: +5, Informative. No, wait, anyone can google something and be "informative." I want a +5, Interesting.
Thanks.
Dear Slashdot: next time you want to mess with the site, add a rich-text editor for comments.
I know my Dad used this technique in the 60's or 70's for vector normalization. It was quite valuable on systems that had no hardware floating point divide (and nothing in that era had a hardware square-root).
Being non-iterative it also has a deterministic speed, which is valuable in
real-time applications.
Integer adds/subtracts on floating-point representations were also sometimes used to approximate multiplication and division (by adding/subtracting the
exponent)
This is John Carmack we're talking about. I imagine he knows how to use a code profiler. The approximations it involve are likely to cause bugs. Floating point always involves approximations. If you don't like them, use a better approximation (double precision). But if you're just trying to, say, figure out which pixel to color, and you approximate the pixel to a few decimal places...I think you're good to go.
I mean, it's not like they're running scientific simulations with this. It's Quake3. Furthermore, converting floating-points to integers and then doing calculations on them is a trick that has been known for years, long before Quake3. They weren't converting floats to ints. They manipulated the bitwise representation of the float. I'm not sure if that's what you meant, though.
:(){
I think I have found a similar solution for the reciprocal of the FOURTH root. The code looks almost the same, but it requires a new constant and you shift the bits 2 places instead of just 1. float Inv4thrt(float x) { float x0 = x; int i = *(int*) // get bits for floating value
i = 0x4F541EEF - (i>>2); // gives initial guess y0
x = *(float*) // convert bits back to float
x = (x/4.0f)*(5 - x0 * x*x*x*x); // Newton step, repeating increases accuracy
return x;
}
Note that the constant I have here is not very carefully tuned so the error may be slightly larger than with the sqrt.
Pretty cool, I think.
Not so much _faster_ than _guaranteed_ execution time for any given precision required (and if you have 480 pixels on axis on the screen you can play with that for quite a lot).
This is why console games (ps, ps2, xbx, 360, bla bla bla huj) actually stays competitive to PC (more powerful, of course) - since developers has a good idea about actual CPU/GPU available at any given moment, they can safely close to the border way more confidently than on pc. And on PC they usually resort to generic 'will give you the best that I can' routines anyway.
(at least that what I can say after observing xbox360 devel team for 6 months. scary stuff, they do, scary stuff.)
The point is that pointer-based type punning isn't really allowed by the language definition. The optimizer can take advantage of that to emit simpler code that, in this case, produces the wrong answer. Using a union short-circuits that kind of optimization.
This isn't to say any particular Gcc produces wrong answers with the code as written, but if you complained about one that did, they would just laugh at you and (if they liked you enough) tell you to rewrite it like the above instead.