Closed WormPatch closed 2 years ago
so yes, the way is by modifing panic source code, that is painful af, i want it to be in my dev profiles
i dont understand what is wrong with this is totally optional and its sane in correct code
How do you prove that the code is correct? Testing is not sufficient, as mentioned above, "works on my machine" does not imply safety.
Plus, what are you worried about a panic if it just aborts the program? A panic that just aborts should have almost no impact on performance.
i dont understand what is wrong with this is totally optional and its sane in correct code
How do you prove that the code is correct? Testing is not sufficient, as mentioned above, "works on my machine" does not imply safety.
Plus, what are you worried about a panic if it just aborts the program? A panic that just aborts should have almost no impact on performance.
well, in process as minimax where some easy task is repeated a lot of times it an affect a little bit, not too much, but a little bit. and i think adding this is good idea, maybe making it a little harder to implement. but this would/will make rust more general propouse programming language. i mean its already but there are levels of how general it can be
i dont understand what is wrong with this is totally optional and its sane in correct code
How do you prove that the code is correct? Testing is not sufficient, as mentioned above, "works on my machine" does not imply safety. Plus, what are you worried about a panic if it just aborts the program? A panic that just aborts should have almost no impact on performance.
well, in process as minimax where some easy task is repeated a lot of times it an affect a little bit, not too much, but a little bit. and i think adding this is good idea, maybe making it a little harder to implement. but this would/will make rust more general propouse programming language. i mean its already but there are levels of how general it can be
Most of the time, "easy" panic branches that can be manually verified can also be identified by the compiler and elided during optimization, so it has almost no performance impact.
i dont understand what is wrong with this is totally optional and its sane in correct code
How do you prove that the code is correct? Testing is not sufficient, as mentioned above, "works on my machine" does not imply safety. Plus, what are you worried about a panic if it just aborts the program? A panic that just aborts should have almost no impact on performance.
well, in process as minimax where some easy task is repeated a lot of times it an affect a little bit, not too much, but a little bit. and i think adding this is good idea, maybe making it a little harder to implement. but this would/will make rust more general propouse programming language. i mean its already but there are levels of how general it can be
Most of the time, "easy" panic branches that can be manually verified can also be identified by the compiler and elided during optimization, so it has almost no performance impact.
optimizations are good but I can't trust them 100% of the time
Do you have specific benchmarks that demonstrate the speed problem you think exists?
Do you have specific benchmarks that demonstrate the speed problem you think exists?
no because i cant remove panic edit: but i know bad minimax (recursive), is performance sensitive
You could construct an example where all panic paths have been manually replaced with unsafe panicless options, such as unwrap_unchecked for Option/Result, and get_unchecked for indexing
You could construct an example where all panic paths have been manually replaced with unsafe panicless options, such as unwrap_unchecked for Option/Result, and get_unchecked for indexing
manually? i dont know asm enought to do that
One thing that used to work when not using std, is simply calling unreachable_unchecked()
in the panic handler. That used to remove all panic paths. Not sure if it still does.
Also from some testing I did (though also a long time ago) is that bounds checks are basically free when working with floating point numbers, but when working with integer data, it's not entirely free.
I’m so sorry about that assign, CryZe! I’ll blame this one on a playful otter ^^
More on topic, the current panic = abort
implementation already utilizes the intrinsics::abort
intrinsic that unconditionally generates an ud2
on platforms other than windows, unix and a few other exceptions. This will produce largely the maximally small code that still honors the prescribed properties of panics.
It is important to remember that the definition of panics do not require that they are unreachable, only that they do not return normally. unreachable_unchecked
does not honor that property today, despite its signature. As such, unreachable_unchecked
is not a suitable implementation for panic without changing at least the way panic is defined. Doing so would be a breaking change and require a Rust two-point-oh.
@WormPatch You don't need to know any assembly to make the benchmarks.
1) write some code that is normal code with panicking. 2) the also write a version that computes the same thing but uses various forms of "unreachable" 3) benchmark the two sets of code.
I strongly suspect that there will not be a huge difference. If there is a significant difference you can demonstrate, people will probably be willing to try and reduce the difference (while maintaining safe code).
However, without a specific benchmark to discuss, or other form of specific evidence, this proposal amounts to you just guessing that there will be a difference even though you admit that you've never written a program to try it.
@WormPatch You don't need to know any assembly to make the benchmarks.
- write some code that is normal code with panicking.
- the also write a version that computes the same thing but uses various forms of "unreachable"
- benchmark the two sets of code.
I strongly suspect that there will not be a huge difference. If there is a significant difference you can demonstrate, people will probably be willing to try and reduce the difference (while maintaining safe code).
However, without a specific benchmark to discuss, or other form of specific evidence, this proposal amounts to you just guessing that there will be a difference even though you admit that you've never written a program to try it.
i have tried minimax of course, the first i do to test a lang is chess minimax, python does 2 depth, C# 5 depth, and Rust 8 depth. i have lost Rust one (i used rm command wrong), i will make it and i will benchmark
@WormPatch You don't need to know any assembly to make the benchmarks.
- write some code that is normal code with panicking.
- the also write a version that computes the same thing but uses various forms of "unreachable"
- benchmark the two sets of code.
I strongly suspect that there will not be a huge difference. If there is a significant difference you can demonstrate, people will probably be willing to try and reduce the difference (while maintaining safe code).
However, without a specific benchmark to discuss, or other form of specific evidence, this proposal amounts to you just guessing that there will be a difference even though you admit that you've never written a program to try it.
what about index bounds? raw pointers are painful
Slices have a get_unchecked
method for unchecked indexing. This is a fairly basic fact about them, and if you're not familiar with at least that much of the standard library then you should probably skim the methods of all the other library types to find out what sorts of unchecked operations are already supported, without any changes to the compiler.
However, tech support for a longer project like this isn't really what the issues of the RFCs repo should be used for. I'd encourage you to ask in one of the many places for Rust programming support:
@WormPatch You don't need to know any assembly to make the benchmarks.
- write some code that is normal code with panicking.
- the also write a version that computes the same thing but uses various forms of "unreachable"
- benchmark the two sets of code.
I strongly suspect that there will not be a huge difference. If there is a significant difference you can demonstrate, people will probably be willing to try and reduce the difference (while maintaining safe code).
However, without a specific benchmark to discuss, or other form of specific evidence, this proposal amounts to you just guessing that there will be a difference even though you admit that you've never written a program to try it.
i dont know how to make unpanic index, using raw pointers is slower, im doing something wrong
I already told you: if you have a slice called data
, you call data.get_unchecked(index)
https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.get_unchecked
Like Lokathor said, slice::get_unchecked()
I already told you: if you have a slice called
data
, you calldata.get_unchecked(index)
https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.get_unchecked
that is literally 25% slower than raw pointers one
Well, you should show some specific code and people can try to figure out what's wrong.
But again, you should use one of the other mediums I mentioned before. RFCs repo issues are not the place for tech support.
Well, you should show some specific code and people can try to figure out what's wrong.
But again, you should use one of the other mediums I mentioned before. RFCs repo issues are not the place for tech support.
yes but im trying to get to my point, sometimes a task uses too much index and stuff, and i know it doesnt care in most apps, because that apps are maded to be user efficent or market efficent, so cleaning errors is the best option. but people like me that wants to make heavy calcs or embedding. its important to make the final product efficent, because bound check is fast but index is fast too so bound check can be important. its just having the good of both sides
I promise you that you will get exactly nowhere with this feature request if you can't or won't produce real examples motivating your request.
Please take the advice of others: this isn't really a place for tech support.
get_unchecked()
25% slower than direct access? Sounds suspicious. Are you compiling with optimizations?
get_unchecked()
25% slower than direct access? Sounds suspicious. Are you compiling with optimizations?
only --release edit: sorry, my bad, it goes 25% slower WITHOUT --release edit 2: no, --release was optimizing my mega dumb test code, so they both have the almost same assembly
I promise you that you will get exactly nowhere with this feature request if you can't or won't produce real examples motivating your request.
Please take the advice of others: this isn't really a place for tech support.
i cant do it because i havent unpanic, if you want i can try it with C++
You're compiling without --release
and complaining about performance??
You're compiling without
--release
and complaining about performance??
its a test edit: but the compilers is smart enough to skip it
this feature is easy to implement, useful in some cases, it doesn't get worse compile time or runtime. it is only a little unsafe, but the one that uses it assumes his own risk, like unsafe things in rust
Maybe an additional person telling you will help: produce real code that is slower than you want.
I recommend showing the code and generated assembly and explaining what is slow. Include how you generate the assembly (compiler version, build arguments, target, etc).
Then fix that code by manually replacing panics with undefined behavior. Show what changed in the Rust and assembly.
This is the bare minimum I’d expect to prove that your idea would even be beneficial. It’s not enough to cause it to be implemented, but it’s enough to show you are willing to work with others.
My own interpretation is that you are enjoying wasting the time of people that would generally like to help you/Rust get better and it’s rather tiresome.
this feature is easy to implement
you are welcome to implement it and submit a pull request. Then this same discussion will occur there before it gets merged.
(Note that implementing this feature is a waste of time. It would never get merged.)
Maybe an additional person telling you will help: produce real code that is slower than you want.
I recommend showing the code and generated assembly and explaining what is slow. Include how you generate the assembly (compiler version, build arguments, target, etc).
Then fix that code by manually replacing panics with undefined behavior. Show what changed in the Rust and assembly.
This is the bare minimum I’d expect to prove that your idea would even be beneficial. It’s not enough to cause it to be implemented, but it’s enough to show you are willing to work with others.
My own interpretation is that you are enjoying wasting the time of people that would generally like to help you/Rust get better and it’s rather tiresome.
that is the problem i used rm command wrong and deleted all my projects i'm trying to make it from 0 to try it
this feature is easy to implement
you are welcome to implement it and submit a pull request. Then this same discussion will occur there before it gets merged.
the problem is, i don't understand rust compiler code, but i guess this is easy to implement because its probably made with 1 conditional and a function. if this is closed i will try to fork rust compiler
if this is closed i will try to fork rust compiler
feel free to do it before then, no reason to wait!
if this is closed i will try to fork rust compiler
feel free to do it before then, no reason to wait!
i'm trying to clone panic = 'abort' code, but rust compiler is complex af even when code is surprisingly clean
do someone knows where rust matches panic handling?
Like BurntSushi said, please use one of the other communication systems that I posted before, because this is not for tech support.
Like BurntSushi said, please use one of the other communication systems that I posted before, because this is not for tech support.
* https://www.reddit.com/r/rust/ * https://users.rust-lang.org/ * https://discord.com/invite/rust-lang-community
srry
sum, subtraction, division, multiplication, index.etc are common operations, i would like a clean way to uncheck them all, making a cleaner asm. there is nothing wrong there, sometimes you just want panics at testing and developing, and leaving it free at release.
Even without explicit invitation, this thread was sufficient to get me curios (nerd snipe me) into coming up with an experiment / micro benchmark.
The benchmark iterates over pairs of integers embedded in the binary and divides them, summing the results. This should contain at least two potentially panicking operations: divide-by-zero and indexing. I didn't get around to looking at the asm and currently do not have access to linux machine where I can get performance counters.
The benchmark was run in three configurations:
stable-abort
: Uses only stable features with panic=abort
.unstable-immediate-abort
: Uses a re-built libcore
with the panic_immediate_abort
feature enabled.unsafe-immediate-unreachable
: Uses a patched libcore
where the aborts from panic_immediate_abort
were replaced by unreachable_unchecked()
.stable-abort |
unstable-immediate-abort |
unsafe-immediate-unreachable |
|
---|---|---|---|
.text size | 741b | 661b | 613b |
mean runtime | 1.009s | 1.408s | 0.906s |
Make of this what you will. My takeaways are:
unstable-immediate-abort
.Edit/Disclaimer: I didn't spent too much time on this, especially not on analyzing the results, so the benchmark may be flawed in a myriad of ways. The primary purpose was to see how/if it was possible to mark every panic "unreachable", and what the impact of that would be.
I'd argue that benchmark is meaningless (cool, but meaningless). Maybe even proving our point. With profiling you can very easily spot the problem (if there is one) and fix it by introducing one usage of unsafe
(for the division; if you remove the black_box()
LLVM optimizes the indexing correctly). Maybe even swap the loop and assert j != 0
, getting it safely. This is exactly the best usage of unsafe
in Rust: specific, after benchmarking, easy to justify (of course you should make the function unsafe
if you don't assert it). Global dispanicking makes no sense, neither here nor probably in any other place.
I'd argue that benchmark is meaningless
I agree! This was firmly in the "was so interested in whether I could, that I didn't stop to think if I should" territory.
This is exactly the best usage of unsafe in Rust: specific, after benchmarking, easy to justify
Strong +1 to that.
Even without explicit invitation, this thread was sufficient to get me curios (nerd snipe me) into coming up with an experiment / micro benchmark.
The benchmark iterates over pairs of integers embedded in the binary and divides them, summing the results. This should contain at least two potentially panicking operations: divide-by-zero and indexing. I didn't get around to looking at the asm and currently do not have access to linux machine where I can get performance counters.
The benchmark was run in three configurations:
* `stable-abort`: Uses only stable features with `panic=abort`. * `unstable-immediate-abort`: Uses a re-built `libcore` with the `panic_immediate_abort` feature enabled. * `unsafe-immediate-unreachable`: Uses a patched `libcore` where the aborts from `panic_immediate_abort` were replaced by `unreachable_unchecked()`.
stable-abort
unstable-immediate-abort
unsafe-immediate-unreachable
.text size 741b 661b 613b mean runtime 1.009s 1.408s 0.906sMake of this what you will. My takeaways are:
* There is a measurable difference in considering panics unreachable, though I imagine that explicit and targeted use of "unchecked" function could get most of the same performance. * I'm a bit surprised at the slowness of `unstable-immediate-abort`. * There's a reasonably easy way to get what @WormPatch wants by (ab)using (very) unstable features. This could at least serve as a base for more comprehensive benchmarks.
Edit/Disclaimer: I didn't spent too much time on this, especially not on analyzing the results, so the benchmark may be flawed in a myriad of ways. The primary purpose was to see how/if it was possible to mark every panic "unreachable", and what the impact of that would be. Click to see benchmark code
Thanks for doing the technical analysis that I didn't do because I didn't know how. do you have the result in asm?
this feature is easy to implement, useful in some cases, it doesn't get worse compile time or runtime. it is only a little unsafe, but the one that uses it assumes his own risk, like unsafe things in rust
@WormPatch actually this isn't really true. Without enabling more aggressive optimizations, this feature has virtually no impact on performance because a branch that continues vs a branch that aborts have no difference at all if compiler does not try to infer that one of the branches never gets hit.
@WormPatch actually this isn't really true. Without enabling more aggressive optimizations, this feature has virtually no impact on performance because a branch that continues vs a branch that aborts have no difference at all if compiler does not try to infer that one of the branches never gets hit.
Technically this is true; however, actually you're more likely to get better compile times even because the eliminated branch will save the cost of codegen'ing the panic.
this feature is easy to implement, useful in some cases, it doesn't get worse compile time or runtime. it is only a little unsafe, but the one that uses it assumes his own risk, like unsafe things in rust
@WormPatch actually this isn't really true. Without enabling more aggressive optimizations, this feature has virtually no impact on performance because a branch that continues vs a branch that aborts have no difference at all if compiler does not try to infer that one of the branches never gets hit.
most functions can't optimize it because inputs are unknown or compilers are not smart enough (yes, even with Rust+LLVM)
I'd argue that benchmark is meaningless (cool, but meaningless). Maybe even proving our point. With profiling you can very easily spot the problem (if there is one) and fix it by introducing one usage of
unsafe
(for the division; if you remove theblack_box()
LLVM optimizes the indexing correctly). Maybe even swap the loop and assertj != 0
, getting it safely. This is exactly the best usage ofunsafe
in Rust: specific, after benchmarking, easy to justify (of course you should make the functionunsafe
if you don't assert it). Global dispanicking makes no sense, neither here nor probably in any other place.
tell me why its "no sense" to you
tell me why its "no sense" to you
Because of what I said a sentence earlier.
tell me why its "no sense" to you
Because of what I said a sentence earlier.
you cant depend of compiler optimization all time, and again, remember that compiler cant optimize it with functions inputs because inputs are unknown
In fact, the whole point of unreachable_unchecked
is to allow the compiler to optimize it by asserting that a certain condition is met. If we do not consider any compiler optimizations, this whole discussion is completely pointless because the performance gain from removing a branch alone is close to zero.
unreachable_unchecked is a way to tell the compiler: "this will never happend", example:
if we replace
panic!()
withunreachable_unchecked()
, this function converts into:what happened here?, we "despanicked" a function.
panic = 'unreachable_unchecked'
in Cargo.toml. will despanic all functions in project. disabling all checks