Live data from Hacker News

Someone’s Been Messing with My Subnormals

moyix.blogspot.com

101–110 of 132 posts

Re: Someone’s Been Messing with My Subnormals

#101
If you are willing to accept the various caveats that come with -ffast-math for your own library, then it looks like it's okay to use -ffast-math during compilation, but not during linking (because it links in crtfastmath.so, as the author points out).

Your own compiled library functions will use the optimizations, but won't force the weird FPU register modes on the rest of the process.

Re: Someone’s Been Messing with My Subnormals

#102
post #67

Earlier quoted context omitted.

Automatic FMA can change the result of operations, so it makes (some) sense to be bundled in with fastmath.

But if what you want is automatic FMA, then why carry along every other possible behavior with it? Just because you want FMA, suddenly NaNs are turned into Infs, subnormal numbers go to zero, handling of sin(x) at small values is inaccurate, etc? To me that's painting numerical handling in way too broad of strokes. FMA also only increases numerical accuracy, it doesn't decrease numerical accuracy, so bundling it with…

"FMA also only increases numerical accuracy, it doesn't decrease numerical accuracy". This strictly speaking isn't true. For example, xx-yy will sometimes be more accurate than fma(x,x, -y*y) (e.g. if x==y). That said, I agree that fma is different from the rest in that it will on average, usually, increase accuracy.

Re: Someone’s Been Messing with My Subnormals

#103
post #93

In D you can opt into specific float algorithms locally rather than a compiler flag. Use of fast math can really really really bite you sometimes, so just being able to opt into using fma and nothing else is awesome.

Yeah, Julia has this also (via a @fastmath macro). It's incredibly nice to be able to apply it safely.

Re: Someone’s Been Messing with My Subnormals

#104

Earlier quoted context omitted.

Anyway, since there aren't any dependencies between a, b, c, and d, I would expect the two divisions to end up basically in parallel in the pipeline. So the critical path is a division and a multiplication either way. Of course that is just a guess.

That assumes you can do multiple divisions in parallel. Back in the good old days, a single division unit was the norm, and it still is on most microcontrollers (assuming they even have hardware floating-point division[1]). Anyone have any references on how the current state of affairs on modern AMD/Intels? [1]: ARM Cortex-M4 for example can have a hardware FPU, but where division and sqrt are optional, see https://d…

https://en.wikichip.org/wiki/intel/microarchitectures/sunny_...

Looks like one FP divider on modern intel. Though you can pack multiple divisions into an instruction.

For AMD I can find throughput numbers but not how many there are, in a brief search. I'd guess two??

Re: Someone’s Been Messing with My Subnormals

#105
post #80

The problem here is that enabling FTZ/DAZ flags involves modifying global (technically thread-local) state that is relatively expensive to do. Ideally, you'd want to twiddle these flags only for code that wants to work in this mode, but given the relative expense of this operation, it's not entirely practicable to auto-add twiddling to every function call, and doing it manually is somewhat challenging because compile…

I don't think flipping these flags is expensive. Can you provide a source for that? AFAICT modern microarchitectures are going to register-rename that into the u-ops issued to the functional units, rather than flush the entire ROB.

https://www.agner.org/optimize/instruction_tables.pdf, search for MXCSR (LDMXCSR and STMXCSR instructions).

Keep in mind that twiddling these flags is going to require saving the MXCSR register to memory, or'ing or and'ing bits in memory, and then reading that memory back into MXCSR. And both saving and reading the MXCSR requires stalls, because floating point operations both read and write that register. So you require, minimum, 4 L1 cache hits and 2 partial pipeline flushes to twiddle a MXCSR bit.

(As far as I'm aware, modern microarchitectures generally don't register-rename the floating-point status register.)

Re: Someone’s Been Messing with My Subnormals

#107
post #80

Earlier quoted context omitted.

I don't think flipping these flags is expensive. Can you provide a source for that? AFAICT modern microarchitectures are going to register-rename that into the u-ops issued to the functional units, rather than flush the entire ROB.

https://www.agner.org/optimize/instruction_tables.pdf , search for MXCSR (LDMXCSR and STMXCSR instructions). Keep in mind that twiddling these flags is going to require saving the MXCSR register to memory, or'ing or and'ing bits in memory, and then reading that memory back into MXCSR. And both saving and reading the MXCSR requires stalls, because floating point operations both read and write that register. So you req…

Looks like many x86 cores still do rename MXCSR, though Gracemont notably doesn't: https://chipsandcheese.com/2021/12/21/gracemont-revenge-of-t...

Note that you wouldn't necessarily need to do a read-modify-write -- it'd suffice in most cases to just to save the old value and then reset the whole MXCSR for the scope requiring special treatment.

Re: Someone’s Been Messing with My Subnormals

#108
post #67

Earlier quoted context omitted.

Automatic FMA can change the result of operations, so it makes (some) sense to be bundled in with fastmath.

This isn't really as valid a comparison as you might think it is. The results of operations varying is not the problem with 'fast-math', the problem is that can negatively impact accuracy in catastrophic ways (among other things). Sure, automatic FMA can change the result, but to my knowledge it always gives a more accurate result, not a less accurate one, and the way in which the results may differ is bounded.

fma can give less accurate results, and can give very large differences. for example 1.5floatmax(Float64)-floatmax(Float64) is Inf, while the fma version will give .5floatmax(Float64)

Re: Someone’s Been Messing with My Subnormals

#109

Earlier quoted context omitted.

https://www.agner.org/optimize/instruction_tables.pdf , search for MXCSR (LDMXCSR and STMXCSR instructions). Keep in mind that twiddling these flags is going to require saving the MXCSR register to memory, or'ing or and'ing bits in memory, and then reading that memory back into MXCSR. And both saving and reading the MXCSR requires stalls, because floating point operations both read and write that register. So you req…

Looks like many x86 cores still do rename MXCSR, though Gracemont notably doesn't: https://chipsandcheese.com/2021/12/21/gracemont-revenge-of-t... Note that you wouldn't necessarily need to do a read-modify-write -- it'd suffice in most cases to just to save the old value and then reset the whole MXCSR for the scope requiring special treatment.

Also worth noting that it's not the entire MXCSR that needs to be renamed, but just a handful of status bits, so the logic is likely even cheaper than renaming a GPR.

Re: Someone’s Been Messing with My Subnormals

#110

Earlier quoted context omitted.

That assumes you can do multiple divisions in parallel. Back in the good old days, a single division unit was the norm, and it still is on most microcontrollers (assuming they even have hardware floating-point division[1]). Anyone have any references on how the current state of affairs on modern AMD/Intels? [1]: ARM Cortex-M4 for example can have a hardware FPU, but where division and sqrt are optional, see https://d…

https://en.wikichip.org/wiki/intel/microarchitectures/sunny_... Looks like one FP divider on modern intel. Though you can pack multiple divisions into an instruction. For AMD I can find throughput numbers but not how many there are, in a brief search. I'd guess two??

Interesting! Looks like my guess was off -- mea culpa.
Post reply on HN