First, this question may not be very basic or useful, but I am curious about the reason behind rust's standard library design.
I was looking at the
split_off method in
Vec<T>, inside of it, I found the function named
assert_failed marked with attributes
#[inline(never)]. I know the meaning of both attributes but I could not find any clear reason for doing this here.
Is it related to some kind of optimization or debugging, or is there some other reason?
+ The most likely reason I can come up with is that this is related to backtracing, and these attributes are intended to enable logs such as
alloc::vec::Vec<T,A>::split_off::assert_failed at /rustc/8460ca823e8367a30dda430efda790588b8c84d3/library/alloc/src/vec/mod.rs:2110:13 to be displayed when an assertion failed. However, I am not 100% sure.
Thank you for your help. (and please excuse any errors in my English)
Thank you for your helpful answer! now I think I almost understand.
I have one final question: Is the first effect(generating assembly only once) due to the fact that the code for
assert_failed is separated into an inner function, which is guaranteed to never be inlined?
I've thought that an inner function is like a normal function but scoped to the containing function. Are these two attributes directly related to the first effect? (of course, they guarantee the assembly of the function will never be inlined though)
I am just curious about how the use of these two attributes and the separation of the function are exactly related to every three effects, accordingly.
Thank you again for your response, it was very helpful!
+ after a few hours of googling I understood all three effects clearly!
It seems making non-generic inner functions is quite a common technique.
(of course, two attributes are still useful in the original question)
For those who found this page while searching, the below links might be helpful.
That translates to the
cold attribute in LLVM:
This attribute indicates that this function is rarely called. When computing edge weights, basic blocks post-dominated by a cold function call are also considered to be cold; and, thus, given low weight.
As a demonstration of what SkiFire13 said, indexing uses the same trick: https://rust.godbolt.org/z/aE17b5qPa
That way the branch predictor defaults to assuming those branches won't be taken, so speculation works better and thus the bounds checks are ≈free, and because the code is later the processor can avoid loading it into the instruction cache in the first place.
Thank you for your more detailed answer! I will check out the link you mentioned.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.