Re: [GD-General] The joy of type aliasing and C
Brought to you by:
vexxed72
From: Colin F. <cp...@ea...> - 2003-12-31 03:06:14
|
>>> that claim to adhere to it. These will give you the min, max, >>> radix (FLT_RADIX), precision in digits (FLT_DIG), etc. >>> >>> I feel so ashamed for knowing this stuff... Well, maybe you'd feel a little less ashamed if you took a look at Section 2.1 of Game Programming Gems 2: "Floating-Point Tricks: Improving Performance with IEEE Floating Point" (Yossarian King, Electronic Arts Canada). It's 14 pages of this stuff! It begins like this (which is "aliasing" not "punning", right?): typedef union { int i; float f; } INTORFLOAT; The author points out that "(int)f" costs about 60 cycles on a Pentium II, and then shows the following faster code: INTORFLOAT n; // floating-point number to convert INTORFLOAT bias; // "magic" number bias.i = (23 + 127) << 23; // bias constant = 1 x 2^23 n.f = 123.456f; // some floating-point number n.f += bias.f; // add as floating-point n.i -= bias.i; // subtract as integer // n.i is now 123 - the integer portion of the original n.f The author says this reduces the conversion time from 60 cycles to about 5 cycles (assuming everything is in cache). Wow! Later in the article the author mentions a fast absolute value: INTORFLOAT ftmp; ftmp.f = f; ftmp.i &= 0x7fffffff; f = ftmp.f; But I'm not sure how this compares with the inline __fabs() instruction. The author shows an improved version of the old square-root trick (bit shift followed by add), taking about 16 cycles instead of 80 on a Pentium II; five times faster. The Intel "Software Optimization Cookbook" (2002) has fun items like this: float FastSqrt( float f ) // roughly 5% error { float RetVal; __asm { mov eax, f sub eax, 0x3f800000 sar eax, 1 add eax, 0x3f800000 mov RetVal, eax } return RetVal; } But, check it; they have the following code on p. 157 (taken out of context): return (*((int *)&f) - IT_FTOI_MAGIC_NUM) >> 1; Type punning! Intel compiler? --- Colin |