Earlier quoted context omitted.
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; } ```
Not really in this case; Rav1e runs over blocks of image planes (like say a 16x16 block of a specific 720p color channel), so there is no continuous slice to iterate over.
Rust and C++ on Floating-Point Intensive Code
21–30 of 95 posts
Re: Rust and C++ on Floating-Point Intensive Code
#22Earlier quoted context omitted.
Not really in this case; Rav1e runs over blocks of image planes (like say a 16x16 block of a specific 720p color channel), so there is no continuous slice to iterate over.
Maybe you can use chunks_exact() and chunks_exact_mut(). The _exact versions allow lifting the bounds checks out of the loop and gave me some great performance boosts in image processing code.
I mean maybe? But I probably wouldn't anyway for this case as a slice reference is actually a "fat" pointer (ie twice the size of a normal pointer) and the length of the slice won't be used (the block size is known per kernel); LLVM might delete the length part anyway.
These are automatically generated kernels, so readability isn't the primary concern here.
Re: Rust and C++ on Floating-Point Intensive Code
#23Re: Rust and C++ on Floating-Point Intensive Code
#24So 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…
Re: Rust and C++ on Floating-Point Intensive Code
#25Earlier 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.
Re: Rust and C++ on Floating-Point Intensive Code
#26Earlier quoted context omitted.
Do you have concrete examples of such algorithms?
Some algorithms guarantee that some arithmetic operation(s) applied to 2+ floating point inputs will result in a list of floating point outputs which when summed have exactly the correct result. This gets all screwed up if you mess with the order of operations or the rounding of intermediate results. e.g. https://www.cs.cmu.edu/~quake/robust.html Some keywords to look for: “compensated arithmetic”, “error-free transf…
Re: Rust and C++ on Floating-Point Intensive Code
#27I 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?
Even for slices, using get_unchecked(1..) to get a smaller subslice without bounds checking might be better than pointer arithmetic as long as the slice lengths get optimized away (i.e. they are never used and never passed to non-inlined functions).
Re: Rust and C++ on Floating-Point Intensive Code
#28Earlier 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?
Rust references should in general optimize better because they give stronger aliasing guarantees. Even for slices, using get_unchecked(1..) to get a smaller subslice without bounds checking might be better than pointer arithmetic as long as the slice lengths get optimized away (i.e. they are never used and never passed to non-inlined functions).
Re: Rust and C++ on Floating-Point Intensive Code
#29Earlier quoted context omitted.
Some algorithms guarantee that some arithmetic operation(s) applied to 2+ floating point inputs will result in a list of floating point outputs which when summed have exactly the correct result. This gets all screwed up if you mess with the order of operations or the rounding of intermediate results. e.g. https://www.cs.cmu.edu/~quake/robust.html Some keywords to look for: “compensated arithmetic”, “error-free transf…
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 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...
This is actually my area of research, I could contribute if you point me to an RFC.
Re: Rust and C++ on Floating-Point Intensive Code
#30So 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.
In my experience -Ofast/-ffast-math yields very impressive results for FP code.
If you can tolerate platform-specific variation in the trailing parts of floating point numbers, it's wonderful.