Reputation: 6220
I want to check if an IEEE754 32-bit number has the value of exactly 0.0f (it will occasionally be set to it.) Accumulation errors will be nil as the data will be frequently updated from a sensor. My processor has no hardware FPU, so operations are done in a fairly fast software library. However, it's still hundreds of cycles for things like add, subtract and compare.
So I was wondering why my compiler does this:
240: if(p_viewer->roll != 0.0f)
03FBC B81160 mul.uu w2,#0,w2
03FBE 900A2E mov.w [w14+20],w4
03FC0 900064 mov.w [w4+12],w0
03FC2 9000F4 mov.w [w4+14],w1
03FC4 07E91F rcall __nesf2
03FC6 E00000 cp0.w w0
03FC8 320054 bra z, 0x004072
__nesf2 apparently compares two floating point numbers. Why doesn't it just do a compare against 0.0f in integer form, which is 0x00000000? Is there some reason it doesn't do this or is it just a missed optimisation opportunity?
My compiler is MPLAB C30, a version of GCC v3.23.
Upvotes: 5
Views: 2875
Reputation: 3990
To check against 0.0f you don't need IEEE stuff, like:
int isFloatNull(float f)
{
static float i;
return !memcmp(&i,&f,sizeof i);
}
Upvotes: 0
Reputation: 25739
It is a missed optimization opportunity. 0.f is a special case since it has to do a compare with -0.f and 0.f. But still it would be faster to compare as ints.
Why is it not optimized? I would wager that it is an integration problem. Stuff like this usually falls between chairs. The people who have the task to put together the platform SDK pick a compiler (gcc), a software float library, and manage to glue it together in the best way they can. This works OK in the general case, and there is little motivation for improvement, since software floats generally are super slow anyway. The worst part is not comparison, but all the other stuff.
Simply put, if you have software floats, there is no point in using them if you need performance. Use fixed point for that.
Upvotes: 1
Reputation: 106187
Because -0.0f
also compares equal to 0.0f
, as required by the IEEE-754 standard.
You could replace the call with a comparison against the integer representations of both -0 (0x80000000
) and +0, if this is a major performance issue. (Or better still, mask the sign bit and compare against 0.0f
).
Upvotes: 7
Reputation: 21628
If this is a IEEE floating point implementation it has to take into account signalling NAN's.
You may not care about that, but the compiler doesn't know that.
Upvotes: 1