4 ms·
> Floating point math is often slower than integer math because the compiler is being conservative about how it optimizes your code. It's not strictly true to
by 14113 2mo ago
> Floating point math is often slower than integer math because the compiler is being conservative about how it optimizes your code.
It's not strictly true to say that it's "being conservative". What is more correct is to say that floating point operations have different semantics to integer operations, and an optimisation that retains the semantics of an expression over integers may not do so when applied to an expression over integers. Hence, it may be possible to apply one optimisation to an integer expression, but applying that to a floating-point expression may result in a different program meaning.
C/C++ compilers give you a way out of this with the `--ffast-math` flag, which essentially allows compilers to relax the constraints on floating-point optimisation passes.
For an example of how this works in GCC, take a look here: https://gcc.gnu.org/wiki/FloatingPointMath https://gcc.gnu.org/wiki/FloatingPointMath
- duped 2mo ago> C/C++ compilers give you a way out of this with the -fast-math People should really use the individual optimization flags they want (no signed zeros, no trapping math, associative math, reciprocal math) and not -ffast-math because the other optimizations it enables leads to surprising code (for example, isinf and isnan may become noops, which will break production code). Basically never use an optimization flag that changes the semantics of your code without understanding exactly what that means. I have had to fix this in a number of codebases because someone thought that flag was as innocuous as -O3. And if you have to enable flush to zero/denormals are zero it should be explicit in your code and scoped.
- 14113 2mo agoYes, I was being a bit concise: Individual optimisations should be turned on as determined by profiling, application semantics, etc. My point was more that if you want to get as close as possible between integer and floating-point, then there is a flag that does it. That doesn't mean that you should do it, however...
- tialaramex 2mo agoYes. In fact, even if you don't ask for semantics like the -fast-math flag, the floating point types are worth some extra time to understand before relying on them. They're much stranger than the machine integers. The machine integers are basically like the Integers you were taught in school, except for overflow. That's not nothing but it's a complexity you can ignore entirely so long as you never overflow. In Rust you can have the language keep you safe - if an overflow occurs we'll panic and we're done. However the floating point types are a weird thing entirely invented for the convenience of the machine. They're too often introduced as if, like the machine integers, they're almost familiar numbers from school. Some languages even call these types "real" - but they very much are not actually the Real numbers, not even the approximation that the machine integers were to actual Integers. The programming language can't help you cope today. You can use software like "Herbie" to help you a bit, but today's languages just leave you with it. https://herbie.uwplse.org/ https://herbie.uwplse.org/ Here's an easy example you saw in school, a tenth, written 0.1 in decimal. The floating point types cannot represent this number. When you ask for the 32-bit floating point value 0.1 in a language like C or Rust, you actually get exactly 0.100000001490116119384765625 because that was a number the type can represent and it was deemed "close enough".
- duped 2mo agoI mean I get that novice programmers might get tripped up on floating point representation but if you don't know "f32 can't represent 0.1 exactly" then you shouldn't yet be worried about the nuance of relaxing IEEE 754 compliance for the purposes of performance.
- deleted 2mo ago[deleted]
- afdbcreid 2mo agoThey're not real, they're rationals (well rationals are real but you get it). If you want "simple" rationals, you can use the numerator/denominator scheme. This has its own problems but if you avoid overflows, they are the rationals you were taught in school, just like the integers. The problem is that people (and languages) default to floating-point without understanding the consequences. Many times it does not matter and then floating point are indeed better (if you know how to use them, e.g. not comparing for equality), but sometimes it does.