4 ms·
I’ve traced bugs back to similar issues. The underlying cause is that some floating point operations are underspecified, such that the behavior of some bits in
by jandrewrogers 6y ago
I’ve traced bugs back to similar issues. The underlying cause is that some floating point operations are underspecified, such that the behavior of some bits in the output of some operations are implementation defined. The intent was to allow future microarchitectures to make small refinements in implementation as transistor budgets grew that might flip a bit in some high-precision edge cases.
In practice, some alternative implementations of these instructions treat the underspecification as license to do just enough to clear the threshold of being technically compliant with the standard and no more. This can show up as material differences in output in the least significant bits in some cases.
For floating point intensive algorithms, these small discrepancies and edge cases will occasionally bubble to the surface as material differences in high-level code behavior. My introduction to this class of bug many years ago was an application that was counting things for tax purposes based on geospatial relationships. On AMD, it produced a count that was off by one.
- vbezhenar 6y agoIt's still now clear how small rounding change results with NaN. It would be understandable if some triangle would be off by one pixel on AMD and probably not noticeable. So far it looks like a CPU bug which produces NaN on some input.
- mnarayan01 6y ago0/0 = NaN
- garmaine 6y agoGraphics uses a lot of stacked matrices. Small errors (more than just rounding, but within spec bounds) can add up to make the result non invertable. That results in NaNs.
- andrepd 6y agoIEEE floats are a complete clusterfuck. Sadly too much is already invested in them and transitioning to a new and better format... I don't see it happening without an industry-wide consortium sticking with it.
- phire 6y agoIEEE754 floats are completely fine. They are 100% defined and produce 100% bit identical results across all compliant implementations. The problem is most implementations include a few extra instructions or modes that are not defined in the IEEE spec. The Fast Reciprocal Estimate instruction that caused the issue in this example is one such instruction. It's not defined in the IEEE spec. It's only defined in the x86 spec (and corresponding similar instructions are defined for other architectures). As its name implies, it's not defined to give an exact result. It's designed to be fast and it's designed to be a rough estimate to some level of precision. You should not use such instructions if you care about any kind of accuracy or cross platform reproducibly. Stick to the instructions that are actually defined in the IEEE 754 spec. And stick to one of the recommended rounding modes, make sure all platforms use the same rounding mode.
- SiempreViernes 6y ago> You should not use such instructions if you care about any kind of accuracy This seems like an overly strong statement, as one reading of it is that "Fast Reciprocal Estimate" is just a bad rng function. I guess you mean that it's up to the user to provide their own error estimation?