The article does not mention the possible additional optimisation opportunities that arise in Rust code due to stricter aliasing rules of references. But I don’t have an example in mind. Does anyone know of an example of it happening in real code?
Many C programs are vailid C++ and are faster when compiled with a C++ compiler because of those stricter aliasing and type rules. Like you though I have no examples.
When the optimizer knows writes can't change the reads, it can reorder and coalesce them. The main benefit of that is enabling autovectorization in more cases. Otherwise it saves a few loads here and there.
Not exactly real world, but real code example demonstrating strict aliasing rule in action for C++. https://godbolt.org/z/WvMb34Kea Rust should have even more opportunities of this due to restrictions it has for writable references.
There are 2 main differences between versions with and without strict aliasing. Without strict aliasing compiler can't assume that the result accumulator doesn't change during the loop and it has to repeatedly read/write it each iteration. With strict aliasing it can just read it to register, do the looping and write the result back at the end once. Second effect is that with strict aliasing enabled compiler can vectorize the loop processing 4 floats at the same time, most likely the same uncertainty of counter prevents vecotorization without strict aliasing.
If you want something slightly simpler example you can disable vectorization by adding '-fno-tree-vectorize'. With it disabled there is still difference in handling of counter.
Using restrict pointers and multiple same type input arrays it would probably be possible to make something closer to real world example.
I believe this advantage is currently mostly theoretical, as the code ultimately gets compiled with LLVM which does not fully utilize all the additional optimization opportunities.
In the spirit of the article... there's a few ways in which this could go :)
The first is, we do have some amount of empirical evidence here: Rust had to turn its aliasing optimizations on and off again a few times due to bugs in LLVM. A comment from 2021: https://github.com/rust-lang/rust/issues/54878#issuecomment-...
> When noalias annotations were first disabled in 2015 it resulted in between 0-5% increased runtime in various benchmarks.
This leaves us with a few relevant questions:
Were those benchmarks representative of real world code? (They're not linked, so we cannot know. The author is reliable, as far as I'm concerned, but we have no way to verify this off-hand comment directly, I link to it specifically because I'd take the author at their word. They do not make any claim about this, specifically.)
Those benchmarks are for Rust code with optimizations turned off and back on again, not Rust code vs C code. Does that make this a good benchmark of the question, or a bad one?
These were llvm's 'noalias' markers, which were written for `restrict` in C. Do those semantics actually take full advantage of Rust's aliasing model, or not? Could a compiler which implements these optimizations in a different way do better? (I'm actually not fully sure of the latest here, and I suspect some corners would be relying on the stacked borrows vs tree borrows stuff being finalized)