3 ms·
Let's change the example to pub fn f(v: &mut [u8]) { let vlen = v.len(); for i in range(0, vlen) { let x = &mut v[i];
by pbsd 12y ago
Let's change the example to
pub fn f(v: &mut [u8]) {
let vlen = v.len();
for i in range(0, vlen) {
let x = &mut v[i];
test::black_box(x); // do some work with x
}
}
The output assembly of latest nightly of rustc is:
f::h1371efe4e4343230faa:
cmp rsp, qword ptr fs:[112]
ja .LBB0_2
movabs r10, 16
movabs r11, 0
call __morestack
ret
.LBB0_2:
push rbp
mov rbp, rsp
push rax
mov rax, qword ptr [rdi + 8]
test rax, rax
je .LBB0_5
mov rcx, qword ptr [rdi]
xor edx, edx
lea rsi, qword ptr [rbp - 8]
.LBB0_4:
lea rdi, qword ptr [rcx + rdx]
inc rdx
mov qword ptr [rbp - 8], rdi
cmp rdx, rax
jb .LBB0_4
.LBB0_5:
add rsp, 8
pop rbp
ret
- Animats 12y agoThanks. I don't see a call to test::black_box(x), so I assume that was an empty function optimized out. Would you change "let vlen = v.len()" to "let vlen = v.len() + 1" and try again, please? That introduces an off-by-one error and a buffer overflow. Let's see what the compiler does with it. Thanks.
- pbsd 12y agoYour modification results in the inclusion of a bounds check in the inner loop: .LBB0_4: cmp rdx, rsi jae .LBB0_7 At `LBB0_7` is a call to `panic_bounds_check`.
- masklinn 12y ago> Thanks. I don't see a call to test::black_box(x), so I assume that was an empty function optimized out. black_box is and does nothing, its purpose is to be opaque to the optimiser and make values it is passed "used" for optimiser purposes, otherwise the optimiser would remove the whole thing since it's a noop.
- Animats 12y ago(Replying to message below, indent limit reached). The panic check is inside the loop, not hoisted out of the loop? OK, that means it's only optimizing bounds tests out when it can, not hoisting them out of loops. That's not bad for a compiler in the early stages. Is a matrix multiply free of checks in the inner loops? That's a good test, because most numerical code has a lot of matrix multiplies underneath. A useful goal is to have most of the inner loops from algorithms in Numerical Recipes free of unnecessary subscript checks. If that can be done, is the "unsafe" stuff necessary at all?
- kibwen 12y agoAt the limit, `unsafe` blocks would still be necessary for any FFI used to call into C code, which is trivially proven unsafe. It's mistaken to think of `unsafe` as a novel language feature. All other languages merely defer their unsafe shenanigans to native C calls. I can just as easily write a memory-unsafe program in Python. In Rust, we use `unsafe` to hoist logic out of C wherever possible, to make our code even more safe; even the unsafe dialect of Rust is safer than C.