   Fastest Float Comparation
  Hi!do you know, what is the fastest way for determine if a float is different from Zero? on C.I've heart that the standard way ( numb != 0.0f )   isn't the optimal way.   
  Depends on your processor, compiler and where it's stored really.Assuming that you never encounter -0 then an IEEE float will have a bit pattern of zero, so you can cast it into an appropriately-sized integer unit and compare it against zero. But if you're already doing calculations on it, i.e. not just grabbing it from memory, then it's probably a better idea to let the compiler work it out for itself. Don't forget to check out the compiler's output either. If you're lucky it might have figured this trick by itself.Also, you may get much greater performance gains from eliminating the branches by using special SIMD instructions to handle the zero cases (for certain basic operations at least).Still, I wouldn't worry about it unless it's in a major inner-loop.   ;  I would worry about a numeric algorithm that relies on a floating-point number being equal to zero.   ;Quote:Original post by ToohrVykI would worry about a numeric algorithm that relies on a floating-point number being equal to zero.Perhaps it's some kind of underflow fixup, or the classical division-by-zero special case.In any case I don't think it's *that* uncommon.   ;  I think maybe what you were told was actually what ToohrVyk said.An algorithm that relies on fp numbers being exactly equal zero is, well, shaky. As such, it's often far from optimal.I really don't think it's an issue performance-wise, though.   ;Quote:Original post by SpoonbenderI think maybe what you were told was actually what ToohrVyk said.Doh.. I read it as "I wouldn't worry about [the performance of] a numeric algorithm that relies on a floating-point number being equal to zero.".In which case I agree somewhat, although it's still a lot better than comparing against arbitrary non-zero constants.;  First, it's probably a premature optimization.I doubt that a comparison against zero is a real bottleneck in your app.You're going to see bigger problems from cache misses and data alignment than the time needed for comparison against zero.That said, using today's Pentium and AMD chips, using today's compilers, just use this: if ( 0 == myfloat ) { ... }The compiler is smart enough to figure out if 0 should be an int, double, float, long double, or whatever else you might be using.The nature of the chips mean that some of the methods mentioned (convert to integer and compare with zero) are going to be incredibly slow.  It's been a while, but I believe there is a "compare with floating point zero" CPU instruction.  If not, load zero followed by compare is going to be faster than the cost of moving it out of the FP registers into an integer register.In summary:Take the obvious comparison choice.  The people who write compiler optimizers are expecting it.Second, don't bother with this type of 'optimization' until you've profiled your app and figured out what the real problems are.   ;Quote:Original post by frobThe nature of the chips mean that some of the methods mentioned (convert to integer and compare with zero) are going to be incredibly slow.For the record I didn't suggest converting it to an integer but rather reading the memory cell it occupies as an integer. Which probably helps performance a bit if you don't perform floating point calculations on it, i.e. only basic data-shuffling.It certainly is a micro-optimization however.   ;Quote:Original post by doynaxAssuming that you never encounter -0 then an IEEE float will have a bit pattern of zero, so you can cast it into an appropriately-sized integer unit and compare it against zero. That is two big reasons NOT to do something fancy.Negative zero will cause problems.  The time required to cast from a floating point number into an integer is going to take a lot of time.Quote:Original post by doynaxBut if you're already doing calculations on it, i.e. not just grabbing it from memory, then it's probably a better idea to let the compiler work it out for itself. Don't forget to check out the compiler's output either. If you're lucky it might have figured this trick by itself.Most compilers will handle the simple comparison ( 0 == foo ) in their optimizers.  It's a common enough thing that even bad optimizers ought to know about it.Quote:Original post by doynaxAlso, you may get much greater performance gains from eliminating the branches by using special SIMD instructions to handle the zero cases (for certain basic operations at least).Not necessarily.  Branch predition is handled rather nicely both on the CPU and by compilers.  Many compilers will optimize the code so that it doesn't matter which branch is taken, there will be no performance hit.  They might put other instructions after the comparison, giving enough time to get through the pipeline.  There are instructions that can handle both sets of branches without stalling the pipeline.  Rely on the compiler unless you have profiled and know that it's an issue.SIMD instructions can also cause slowdowns.  It's not a free operation to move values in and out of SIMD structures, nor to set up the states.  Let the optimizing compiler vectorize the code.  Unless you REALLY know the machine code and operation, you'll be better off relying on the implementation provided by the compiler writers who know it very well.Quote:Original post by doynaxStill, I wouldn't worry about it unless it's in a major inner-loop.I wouldn't worry about it even if it were in a major inner-loop.  I'd be more worried about having the major inner loop in the first place, and picking an algorithm that doesn't require it.frob.   ;Quote:Original post by frobNegative zero will cause problems.  The time required to cast from a floating point number into an integer is going to take a lot of time.Exactly, which is I've repeatedly stated that you shouldn't try to do it on the result of a calculation. If it's already just an anonymous chunk of memory in a big array then you may as well treat it as an integer.Quote:Original post by frobMost compilers will handle the simple comparison ( 0 == foo ) in their optimizers.  It's a common enough thing that even bad optimizers ought to know about it.I couldn't get VC6 to do this last time I tried. I guess it can't just assume that you won't encounter negative zeroes..Quote:Original post by frobQuote:Original post by doynaxAlso, you may get much greater performance gains from eliminating the branches by using special SIMD instructions to handle the zero cases (for certain basic operations at least).Not necessarily.  Branch predition is handled rather nicely both on the CPU and by compilers.  Many compilers will optimize the code so that it doesn't matter which branch is taken, there will be no performance hit.  They might put other instructions after the comparison, giving enough time to get through the pipeline.  There are instructions that can handle both sets of branches without stalling the pipeline.  Rely on the compiler unless you have profiled and know that it's an issue.Yes, branch prediction works great if the branches are predictable, such as if the zeroes are a rarely encountered special case. If it's a common and seemingly random occurance then you may well be in trouble..Quote:Original post by frobSIMD instructions can also cause slowdowns.  It's not a free operation to move values in and out of SIMD structures, nor to set up the states.  Let the optimizing compiler vectorize the code.  Unless you REALLY know the machine code and operation, you'll be better off relying on the implementation provided by the compiler writers who know it very well.I didn't mean to suggest doing it on a single element, my point was rather that they OP should probably look elsewhere for the big speedups if this is part of a critical innerloop. And a future vectorization of the inner-loop is likely to render the zero detection hack useless.I do think you're giving the compiler a bit much credit regarding SIMD code however, in my experience they still require a bit of guidance to generate half-decent SIMD code. At the very least you have to provide decent memory alignment and prevent aliasing for the compiler to even try.Quote:Original post by frobQuote:Original post by doynaxStill, I wouldn't worry about it unless it's in a major inner-loop.I wouldn't worry about it even if it were in a major inner-loop.  I'd be more worried about having the major inner loop in the first place, and picking an algorithm that doesn't require it.frob.Uhh, you should certainly always search for alternative algorithms. But that applies to all inner-loops..   