5 ms·
Note that Rust also traps on integer overflow, and it is trivial to „hack“ the compiler to disable this, and many have done so. While on this microbenchmark yo
by fluffy87 6y ago
Note that Rust also traps on integer overflow, and it is trivial to „hack“ the compiler to disable this, and many have done so.
While on this microbenchmark you see a 3x slowdown with the LLVM backend, on large Rust projects like servo, Firefox, the rust compiler, etc. the slowdown is not even measurable.
Also, Rust provides you with unsafe intrinsics to opt-out of trapping in the particular line of code in which it causes an issue.
- lytigas 6y agoRust wraps in release mode and traps in debug mode[0][1]. All large projects that I know of ship in release mode. Though I'd be interested to see a source for it not pessimizing badly. [0] https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=53775b20e6cee7611659aa44e63c2a4b https://play.rust-lang.org/?version=stable&mode=release&edit... [1] https://github.com/rust-lang/rfcs/pull/560 https://github.com/rust-lang/rfcs/pull/560
- sanxiyn 6y agoIt is quite believable that trapping does not slow down Firefox. GCC is part of SPECint, and trapping is known not to slow down SPECint GCC. (It does slow down other SPECint benchmarks.)
- fluffy87 6y agoSee my reply to masklin in this thread for why this is incorrect. In release mode, the behavior of integer overflow in Rust is not UB/cannot happen, but modulo two arithmetic. These two are not the same thing.
- tom_mellior 6y agoHuh? Parent wrote: >> Rust wraps in release mode and traps in debug mode You wrote: > In release mode, the behavior of integer overflow in Rust is not UB/cannot happen, but modulo two arithmetic. The parent didn't claim or imply that overflow is UB. The parent wrote that it "wraps", which is equivalent to your "modulo two arithmetic". You are not in disagreement, so why are you disagreeing?
- djrenren 6y agoI dont think Rust traps on overflow in release builds
- carlmr 6y agoThat's correct, it's not a zero-cost abstraction. Also the wrapping types aren't unsafe, they just make it explicit.
- fluffy87 6y ago. In release mode, the behavior of integer overflow in Rust is modulo two arithmetic instead of not UB/cannot happen. These two are not the same thing. See my reply to masklin.
- masklinn 6y ago> Note that Rust also traps on integer overflow, and it is trivial to „hack“ the compiler to disable this, and many have done so. “Hack” is a completely unsuitable term, there’s a simple and official compilation flag which can be flipped on or off. It’s also misleading to say that Rust will trap on overflow: rustc enables overflow checking by default in debug mode, but disables it in release.
- fluffy87 6y agoThat’s unfortunately incorrect. That flag does not turn integer overflow into UB, which is what allows the C++ optimizations that assume it cannot happen, and can be used to prove that loops terminate, etc. That flag changes the behavior of integer overflow from trapping to “modulo 2 arithmetic”. If you want to change the behavior of integer overflow in Rust to “always assume it cannot happen”, you need to “hack” the compiler AFAIK. If you believe this is incorrect, provide the flag that proves that (hint: such a flag makes safe Rust unsound and it therefore does not exist).
- masklinn 6y ago> That’s unfortunately incorrect. That flag does not turn integer overflow into UB I've never claimed any such thing. Integer overflow is defined in Rust. > That flag changes the behavior of integer overflow from trapping to “modulo 2 arithmetic”. Yes? > If you want to change the behavior of integer overflow in Rust to “always assume it cannot happen”, you need to “hack” the compiler AFAIK. What I quoted was about rust "trapping" on integer overflow and having to "hack" it in order to make it not trap.
- kevincox 6y agoI find this decision frustrating. They made it clear by making it trap in debug that this is a "bug" but denied the optimization benefits of calling it undefined behaviour on release. I'm assuming the rationalization is "wrapping is better than undefined behaviour" but I have not seen any evidence that the average program is actually more likely to behave correctly in the face of wrapping. The combinations that make the most sense to me are: 1. debug: trap, release: trap. Bad performance, correct. 2. debug: wrap, release: wrap. Good performance 3. debug: trap, release: undefined. Great performance. I guess my point is make up your mind. Is "overflow" allowed and wrapping or a bug?
- eddyb 6y ago> but I have not seen any evidence that the average program is actually more likely to behave correctly in the face of wrapping. Rust takes a simple stance of "safe code should be UB-free". Yes, you may have logic bugs with wrapping, but you can't cause memory unsafety with it in, because things like array/slice bound checks aren't ever disabled. Also, C relies on undefined signed overflow for things like "`for` loops incorrectly using `int` instead of `size_t` because it's easier to type", which doesn't really apply to Rust (which require `usize`, the `size_t` equivalent, for indexing, and has pointer-range-based iterators for slices), so I doubt UB overflow in Rust would help performance much. It would be trivial to change `rustc_codegen_llvm` to set LLVM's `nsw`/`nuw` (in order to make signed/unsigned overflow UB), if you want to prove it improves performance somewhere.