Remix.run Logo
OptionOfT 15 hours ago

Apart from multi threading, there is more information in the Rust type system. Would that would allow more optimizations?

kouteiheika 15 hours ago | parent | next [-]

Yes. All `&mut` references in Rust are equivalent to C's `restrict` qualified pointers. In the past I measured a ~15% real world performance improvement in one of my projects due to this (rustc has/had a flag where you can turn this on/off; it was disabled by default for quite some time due to codegen bugs in LLVM).

steveklabnik 15 hours ago | parent | next [-]

Not just all &mut T, but also all &T, where the T does not transitively contain an UnsafeCell<T>. Click "show llvm ir" instead of "build" here: https://play.rust-lang.org/?version=stable&mode=release&edit...

marcianx 15 hours ago | parent [-]

I was confused by this at first since `&T` clearly allows aliasing (which is what C's `restrict` is about). But I realize that Steve meant just the optimization opportunity: you can be guaranteed that (in the absence of UB), the data behind the `&T` can be known to not change in the absence of a contained `UnsafeCell<T>`, so you don't have to reload it after mutations through other pointers.

steveklabnik 14 hours ago | parent | next [-]

Yes. It's a bit tricky to think about, because while it is literally called 'noalias', what it actually means is more subtle. I already linked to a version of the C spec below, https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf but if anyone is curious, this part is in "6.7.4.2 Formal definition of restrict" on page 122.

In some ways, this is kind of the core observation of Rust: "shared xor mutable". Aliasing is only an issue if the aliasing leads to mutability. You can frame it in terms of aliasing if you have to assume all aliases can mutate, but if they can't, then that changes things.

salmon640 6 hours ago | parent | prev [-]

[flagged]

dmitrygr 3 hours ago | parent | prev [-]

Do you not use restrict in your normal everyday C code that you write? I use it in my normal C code.

kouteiheika an hour ago | parent [-]

I used to use it, but very rarely, since it's instant UB if you get it wrong. In tiny codebases which you can hold in your head it's probably practical to sprinkle it everywhere, but in anything bigger it's quite risky.

Nevertheless, I don't write normal everyday C code anymore since Rust has pretty much made it completely obsolete for the type of software I write.

mhh__ 15 hours ago | parent | prev | next [-]

Aliasing info is gold dust to a compiler in various situations although the absence of it in the past can mean that they start smoking crack when it's provided.

randomNumber7 12 hours ago | parent | prev | next [-]

In C there is the "restrict" keyword to tell the compiler that there is no other pointer to the values accessed over a certain pointer.

If you do not use that the generated code can be quite suboptimal in certain cases.

adgjlsfhk1 15 hours ago | parent | prev | next [-]

Yes. Specifically since Rust's design prevents shared mutablity, if you have 2 mutable data-structures you know that they don't alias which makes auto vectorization a whole lot easier.

tcfhgj 15 hours ago | parent | prev [-]

what about generics (equivalent to templates in C++), which allow compile time optimizations all the way down which may not possible if the implementation is hidden behind a void*?

OptionOfT 12 hours ago | parent [-]

Unless you use `dyn`, all code is monomorphized, and that code on its own will get optimized.

This does come with code-bloat. So the Rust std sometimes exposes a generic function (which gets monomorphized), but internally passes it off to a non-generic function.

This to avoid that the underlying code gets monomorphized.

https://github.com/rust-lang/rust/blob/8c52f735abd1af9a73941...

dwattttt 5 hours ago | parent [-]

> This does come with code-bloat. So the Rust std sometimes exposes a generic function (which gets monomorphized), but internally passes it off to a non-generic function.

There's no free lunch here. Reducing the amount of code that's monomorphised reduces the code emitted & improves compile times, but it reduces the scope of the code that's exposed to the input type, which reduces optimisation opportunities.

josephg 4 hours ago | parent [-]

Yes. But I like that rust gives you the option.

In C, the only way to write a monomorphized hash table or array list involves horribly ugly macros that are difficult to write and debug. Rust does monomorphization by default, but you can also use &dyn trait for vtable-like behaviour if you prefer.