Live data from Hacker News

Rust and C++ on Floating-Point Intensive Code

reidatcheson.com

31–40 of 95 posts

Re: Rust and C++ on Floating-Point Intensive Code

#31
post #16
post #7

Earlier quoted context omitted.

It doesn't exist yet and it's not clear it should be replicated as is. The fast-math flag does a bunch of related things that should probably be exposed separately so it's not a footgun in several situations. I'm also partial to exposing it per-function so the control is actually in the hands of the people writing the code that know the context and not subject to someone fiddling with compiler flags and getting incor…

> I'm also partial to exposing it per-function so the control is actually in the hands of the people writing the code that know the context As a C++ programmer who routinely uses fast-math "until something breaks" with DSP code, I would find that capability very attractive.

This should probably be exposed as separate floating point types. With relatively cheap conversions. (Mostly done error checks.)

Re: Rust and C++ on Floating-Point Intensive Code

#32
post #3

It's very easy to do FMA's using .mul_add() on floats in Rust, which the author didn't seem to know about.

Ideally the compiler should be able to do this by itself though, at least with the appropriate flag to enable it.

FMA isn't a safe optimization as it can give different results.

C++ compilers have flags to enable it globally. gcc and clang include the optimization in -Ofast.

Rust allows you to choose at a code level (but usually people don't know about it). Perhaps it should also have a global fast-math flag that would automatically optimize it. Pros and cons to that.

Re: Rust and C++ on Floating-Point Intensive Code

#33
The authors ends by noting that FMA would probably have improved the performances for the Rust code.

It is interesting to note that, whereas most ffast-math optimization will trade precision for reduced computing time, adding an FMA can only improve the precision of the output (and thus it is a safe optimization).

Re: Rust and C++ on Floating-Point Intensive Code

#35
post #29

Earlier quoted context omitted.

Fair, I think it would be very helpful for Rust if some expert actually knows of a specific example for which this is the case. I think there is an RFC about enabling floating-point contraction by default, that would "silently" be able to do some of these transformations depending on the optimization level.

The one very important thing that often get destroyed by compiler using associativity is the TwoSum Error free transform which is a vital composant of several algorithms that deal with numerical error (most notably the Kahan Summation). The problem is mentionned in the Wikipedia page of the Kahan summation (and I have been able to reproduce it with gcc) : https://en.wikipedia.org/wiki/Kahan_summation_algorithm#Poss..…

I think the key issue with the optimizations that ICC is performing for C++ but Rust is not doing in this case is just FP-contraction, which is related to, but not the same as, assuming associativity.

The RFC about that is https://github.com/rust-lang/rfcs/pull/2686 , where you see users kind of split into the "I want faster binaries" and "I want more deterministic execution" camps. Neither are wrong TBH.

Some people have tried to show there that enabling FP-contraction by default isn't always better / more precise, but I'm not sure if they succeeded.

Re: Rust and C++ on Floating-Point Intensive Code

#36

I have some experience with this, ie ensuring LLVM optimizes and codegens the "best"! I have been working to generate target independent "kernels" for the Rav1e AV1 encoder and have had to do a lot of unidiomatic things to get LLVM to generate machine code similar in quality to hand written ASM. Granted, this is on integers and not floats, but the same principles should apply. What I've found is that you need to igno…

> index checking is expensive

Seems a little gung ho to disable guaranteed index checking in a video codec no? I know you still do the checks, but it sounds like it's not in a statically guaranteed way.

Re: Rust and C++ on Floating-Point Intensive Code

#37

Earlier quoted context omitted.

Ideally the compiler should be able to do this by itself though, at least with the appropriate flag to enable it.

FMA isn't a safe optimization as it can give different results. C++ compilers have flags to enable it globally. gcc and clang include the optimization in -Ofast. Rust allows you to choose at a code level (but usually people don't know about it). Perhaps it should also have a global fast-math flag that would automatically optimize it. Pros and cons to that.

I wasn't trying to imply it should be on by default. Often one does not care about the lower bits of the floats, but do want the speed. For some tasks it's very much the opposite. Being able to specify a global option with local override is a great combo.

Re: Rust and C++ on Floating-Point Intensive Code

#38

I have some experience with this, ie ensuring LLVM optimizes and codegens the "best"! I have been working to generate target independent "kernels" for the Rav1e AV1 encoder and have had to do a lot of unidiomatic things to get LLVM to generate machine code similar in quality to hand written ASM. Granted, this is on integers and not floats, but the same principles should apply. What I've found is that you need to igno…

the first order reason Rust and C++ differ in the article is because Rust will not pass the ffastmath flag to llvm, not because of any of this stuff.

Re: Rust and C++ on Floating-Point Intensive Code

#39
post #18

It looks like what the author was looking for is [1] f64::mul_add(self, a: f64, b: f64) -> f64 Adding it to the code indeed allows the LLVM to generate the "vfma" instruction. But it didn't significantly improve performance, on my machine at least. $ ./iterators 1000 Normalized Average time = 0.0000000011943495282455513 sumb=89259.51980374461 $ ./mul_add 1000 Normalized Average time = 0.0000000011861410852805122 sumb…

Hum, did the program get vectorized?

Re: Rust and C++ on Floating-Point Intensive Code

#40
post #2

So the difference basically boils down to -ffast-math, right? Is there an equivalent in Rust? Edit: After some search I found these: https://github.com/rust-lang/rust/issues/21690 https://doc.rust-lang.org/core/intrinsics/fn.fadd_fast.html Writing a wrapper around f64 that uses these intrinsics shouldn't be too hard. I don't program in Rust though.

yes, this is all purely down to Rust not doing ffast-math (on purpose)

writing a wrapper is not trivial, at all.

what Rust could do though, is add a wrapped float type, that the compiler will forward to llvm saying "you can ffast-math these" That is the approach Rust tends to take for these kinds of things, though no plans are in the works to do this to make floats vectorizeable yet. Maybe we should start such plans?

Post reply on HN