rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.06k stars 12.69k forks source link

Missed optimization/perf oddity with allocations #128854

Open peterwmwong opened 2 months ago

peterwmwong commented 2 months ago

Consider the following minimized example:

pub fn test() {
    for _ in 0..128 {
        let _ = vec![0; 32];
    }
}

Expected generated output (Rust 1.81.0):

example::test::h15f9c44deb8efbb9:
        ret

Actual output (Rust Nightly):

example::test::h15f9c44deb8efbb9:
        mov     rax, qword ptr [rip + __rust_no_alloc_shim_is_unstable@GOTPCREL]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   ecx, byte ptr [rax]
        movzx   eax, byte ptr [rax]
        ret

Godbolt: https://www.godbolt.org/z/x458Pv8P5

workingjubilee commented 2 months ago

I know this is a "minimal reduction" but is there an example where this impacts actual programs?

Artikae commented 2 months ago

For reference, the actual cause, as far as I can tell, is this line in the alloc function.

// Make sure we don't accidentally allow omitting the allocator shim in
// stable code until it is actually stabilized.
core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);

It, of course, can't be optimized out because it's volatile.

That line doesn't appear in alloc_zeroed, for some reason. (Maybe a bug?)

peterwmwong commented 2 months ago

Just noticed a helpful rundown of the cause, why, and perf potential if fixed (@Kobzol's perf run) in this zulip conversation

saethlin commented 1 month ago

Would you count this as fixed if we make the codegen match by regressing the good case? https://github.com/rust-lang/rust/pull/130497

peterwmwong commented 1 month ago

Bold move @saethlin 😆. I've updated bug description/repro.

Y'all do whatever you want with this, just an observation I made a while back looking into Mojo's claims being faster than Rust.