5 ms·
> Rust does have one additional requirement for a bare metal program: You must define the panic handler. What would panic? Who is doing (and where) the panic c
by scoutt 7y ago
> Rust does have one additional requirement for a bare metal program: You must define the panic handler.
What would panic? Who is doing (and where) the panic checking? Since no additional libraries are being used, is the panic checking in the core library?
What is the overhead of panic checking?
- paavohtl 7y agoThere's no "panic checking". AFAIK in a no_std environment panic simply jumps to the panic handler, which is more or less an ordinary function. As for what can panic, anything that calls the `panic!` macro. For example trying to read an out-of-bounds element from an array will cause a panic.
- scoutt 7y ago> trying to read an out-of-bounds element So I understand there are runtime checks for out-of-bound reading/writing, correct? This has a cost (overhead) and for embedded systems this is valuable information that should be considered when choosing a language.
- Uther 7y agoYou have to be aware of this but most of the time this is not a problem. Most of the useless checks are optimized out, and if you suffer bound check performance somewhere in the program, and you know what you are doing, you can do unchecked indexing using an unsafe block with `get_unchecked()` .
- sjustinas 7y agoThe indexing operator [] does bound checks, the method `get_unchecked()` does not. If you need the extra speed at the expense of safety, you can do it, but you have to consciously choose this trade-off. Unlike in C, in Rust safety is opt-out.
- scoutt 7y agoBut in this case the overhead may come from calling get_unchecked() for every array access, is this correct? Unless the function it's inlined and does a quantifiable amount of work (for a given arch), but this may also have an impact on code size. In a way or another, there should be a trade-off for accessing array elements (a very common operation). I don't know how all of this can be coupled with the embedded ecosystem we are used to work with.
- paavohtl 7y agoget_unchecked() is marked as an #[inline] function (like most other low level primitives), and through the magic of compiler optimization it should have exactly 0 overhead. The function should most likely compile down to a single CPU instruction.
- steveklabnik 7y agoSo, here's a fun example of how this works out in practice: https://godbolt.org/z/DXo25P https://godbolt.org/z/DXo25P Here, rustc is able to see that we always have a first element, and will actually completely remove the unchecked one, and replace the body with the "checked" one, which has no checks. For some reason, I can't get it to show the assembly for just the two functions; it always optimzies everything out. Putting it on the rust playground says this: playground::access_first_element: # @playground::access_first_element # %bb.0: pushq %rax cmpq $2, %rsi jb .LBB5_2 # %bb.1: movq %rdi, %rax addq $4, %rax popq %rcx retq .LBB5_2: movq %rsi, %rdx leaq .L__unnamed_2(%rip), %rdi movl $1, %esi callq *core::panicking::panic_bounds_check@GOTPCREL(%rip) ud2 # -- End function playground::access_first_unchecked: # @playground::access_first_unchecked # %bb.0: leaq 4(%rdi), %rax retq # -- End function as you can see, it gets super inlined, and does no work, compared to the bound checked version.
- scoutt 7y agoThank you and the other users for the patience. I guess in the case of your code, the checks are removed/optimized because the compiler knows the size of the array (since it's static, as in non-dynamically-allocated)? Probably the out-of-bounds runtime checks will (or should be) enforced when it's about dynamically allocated arrays.
- deleted 7y ago[deleted]