It's very easy to do FMA's using .mul_add() on floats in Rust, which the author didn't seem to know about.
Rust and C++ on Floating-Point Intensive Code
11–20 of 95 posts
Re: Rust and C++ on Floating-Point Intensive Code
#12Earlier quoted context omitted.
Ideally the compiler should be able to do this by itself though, at least with the appropriate flag to enable it.
If you’re doing fiddly numerical work, this must definitely be optional, as swapping separate multiplication and addition for FMA (or vice versa) can compromise correctness. In some cases you need two different algorithms if FMA is present or absent.
Re: Rust and C++ on Floating-Point Intensive Code
#13Re: Rust and C++ on Floating-Point Intensive Code
#14Re: Rust and C++ on Floating-Point Intensive Code
#15Earlier quoted context omitted.
If you’re doing fiddly numerical work, this must definitely be optional, as swapping separate multiplication and addition for FMA (or vice versa) can compromise correctness. In some cases you need two different algorithms if FMA is present or absent.
Do you have concrete examples of such algorithms?
e.g. https://www.cs.cmu.edu/~quake/robust.html
Some keywords to look for: “compensated arithmetic”, “error-free transformations”.
FMAs generally speed up these tools, but you need to be careful and deliberate about how they are used.
(Disclaimer: I am not an expert on this, just some guy on the internet.)
Re: Rust and C++ on Floating-Point Intensive Code
#16So 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.
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…
As a C++ programmer who routinely uses fast-math "until something breaks" with DSP code, I would find that capability very attractive.
Re: Rust and C++ on Floating-Point Intensive Code
#17I 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…
Not sure I understand the part about raw pointers. As far as I understand, Rust references will surely turn into pointers at the LLVM IR level?
``` for (i, val) in my_slice.iter().enumerate() { let x = *val + 9999; } ```
Re: Rust and C++ on Floating-Point Intensive Code
#18 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=89259.52037960211
Maybe the performance gap is not due to what the author thought...[1] https://doc.rust-lang.org/std/primitive.f64.html#method.mul_...
Re: Rust and C++ on Floating-Point Intensive Code
#19Earlier quoted context omitted.
Not sure I understand the part about raw pointers. As far as I understand, Rust references will surely turn into pointers at the LLVM IR level?
You can use iterators to avoid unnecessary bounds checking on every element in a slice and you can still get an index to the value. Something like this: ``` for (i, val) in my_slice.iter().enumerate() { let x = *val + 9999; } ```