Live data from Hacker News

Optimizations Enabled by -ffast-Math

kristerw.github.io

51–60 of 117 posts

Re: Optimizations Enabled by -ffast-Math

#51
post #2

The question is how to enable all this in Rust... Right now there's no simple way to just tell Rust to be fast & loose with floats.

I don't know if most Rust programmers would be happy with any fast and loose features making it into the official Rust compiler. Besides, algorithms that benefit from -ffast-math can be implemented in C and with Rust bindings automatically generated. This solution isn't exactly "simple", but it could help projects keep track of the expectations of correctness between different algorithm implementations.

Rust should have native ways to express this stuff. You don't want the answer to be "write this part of your problem domain in C because we can't do it in Rust".

Re: Optimizations Enabled by -ffast-Math

#52
post #38

Earlier quoted context omitted.

And don't do any division. Easy.

There's nothing wrong with divisions if you exclude problematic combinations of input values.

You're going to have to do some intermediate checks if you want stuff like x/sin(x) to behave.

Re: Optimizations Enabled by -ffast-Math

#53

Earlier quoted context omitted.

> Generally if you're seeing a NaN/Inf something has gone wrong That’s a bold claim.

Can you think of a function where the input is valid, the output is NaN and nothing has gone wrong in the process? I can't think of any, haven't experienced any, not heard of any examples of it, so you're welcome to break my ignorance on the subject.

This depends how you define “gone wrong”. In evaluating rational functions (a useful tool for approximating all sorts of other functions), one efficient and well behaved algorithm is the “barycentric formula”, based on interpolating function values at various specific input points. When the input is one of those points directly, this formula results in Inf / Inf = NaN. Evaluation code needs to check for this case, and then replace the output by the appropriate value for the input.

±Inf is a very natural output for many kinds of numerical codes.

Re: Optimizations Enabled by -ffast-Math

#54

Earlier quoted context omitted.

Generally if you're seeing a NaN/Inf something has gone wrong, It's very difficult to gracefully recover from and if you tried I think you would lose both sanity and performance! Regarding performance, the cost of a real division is about 3-4 orders worse performance than an if statement that is very consistent, but the usual way is to have fast/safe versions of functions, where you need performance and can deduce if…

> Generally if you're seeing a NaN/Inf something has gone wrong That’s a bold claim.

it's true in my experience. NaN/Inf was always a bug and resulted in needing to rewrite the calculation

Re: Optimizations Enabled by -ffast-Math

#56
post #12
post #11

I found the following note for -ffinite-math-only and -fno-signed-zeros quite worrying: The program may behave in strange ways (such as not evaluating either the true or false part of an if-statement) if calculations produce Inf, NaN, or -0.0 when these flags are used. I always thought that -ffast-math was telling the compiler. "I do not care about floating point standards compliance, and I do not rely on it. So opti…

> A promise that you will not produce Inf, NaN, or -0.0. Whilst especially Inf and NaN can be hard to exclude. Cumbersome but not that difficult: Range-check all input values.

The checks could be expensive though, more expensive than the gains from this optimization. Often it is better to let the calculation proceed and use isnan to check the final result.

Re: Optimizations Enabled by -ffast-Math

#57

Earlier quoted context omitted.

> Generally if you're seeing a NaN/Inf something has gone wrong That’s a bold claim.

Can you think of a function where the input is valid, the output is NaN and nothing has gone wrong in the process? I can't think of any, haven't experienced any, not heard of any examples of it, so you're welcome to break my ignorance on the subject.

There are algorithms that behave correctly but require intermediate Inf or NaN to work. If I recall there is one related to finding bounding box intersections in ray tracing. I know when I introduce such code into a codebase I put a large "DO NOT CHANGE THIS..." style comment with an explanation so some enterprising programmer doesn't put some if statements in to remove what they think is an error, when it is not.

I'd suspect the same is true for NaN. These things were introduced for reasons. If you don't have a deep knowledge of why, don't assume everyone else is the same.

Edit: I found examples using a NaN and Inf intermediates to get a large speed increase [1,2].

[1] https://tavianator.com/2015/ray_box_nan.html

[2] https://tavianator.com/2011/ray_box.html

Re: Optimizations Enabled by -ffast-Math

#58
post #10
post #8

Earlier quoted context omitted.

Also maybe you woild like to have more granular control over which parts of your program has the priority on speed and which part favours accuracy. Maybe this could be done with a seperate type (e.g. ff64) or a decorator (which would be useful if you want to enable this for someone elses library).

Maybe... or maybe there would be just a flag to enable all this and be fine with consequences.

Reasoning about the consequences along a couple functions in your hot path is one thing. Reasoning about the consequences in your entire codebase and all libraries is quite another.

Re: Optimizations Enabled by -ffast-Math

#59

Earlier quoted context omitted.

Can you think of a function where the input is valid, the output is NaN and nothing has gone wrong in the process? I can't think of any, haven't experienced any, not heard of any examples of it, so you're welcome to break my ignorance on the subject.

Do you count under/overflow resulting in Inf as 'something has gone wrong'? If so, why would gracefully recovering be hard?

Because you're about 15 stack frames deep into some calculation when the problem gets noticed. So how do you handle this? You could throw an exception (or similar), which would allow the UI to state something semi-helpful like 'Calculation failed'. But recover? Usually not.

I think NaN and inf can be really useful in specific cases, but they probably shouldn't be allowed to propagate through your program, and shouldn't occur unless you're specifically making use of them.

Post reply on HN