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
|