SEE-AVX-stall when using target-cpu=znver2. Thus ~25 times slower.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
The performance of the following function is realy slow when i use target-cpu=znver2, my own cpu. Without a target-cpu set it is ~25 times quicker.
fn main() {
let row = std::hint::black_box(& [125u8; 8]);
let mut data = [0u32; 8];
let data = std::hint::black_box(&mut data);
for _ in 0..500_000_000u64 {
std::hint::black_box(slow(*row, data));
}
}
#[inline(never)]
pub fn slow(mut row: [u8; 8], data: &mut [u32; 8]) -> [u8; 8] {
for data in data {
*data <<= 5;
}
row[7] = 0;
row
}
I have run it twice with perf. Once with the target-cpu set and once without:
$ RUSTFLAGS="-C target-cpu=znver2" perf stat -e "sse_avx_stalls" cargo run --release
Compiling perf_test v0.1.0 (/home/barfussmann/Documents/perf_test)
Finished release [optimized + debuginfo] target(s) in 0.20s
Running `target/release/perf_test`
Performance counter stats for 'cargo run --release':
10.486.365.719 sse_avx_stalls:u
32,070525175 seconds time elapsed
31,812318000 seconds user
0,125145000 seconds sys
$ perf stat -e "sse_avx_stalls" cargo run --release
Compiling perf_test v0.1.0 (/home/barfussmann/Documents/perf_test)
Finished release [optimized + debuginfo] target(s) in 0.19s
Running `target/release/perf_test`
Performance counter stats for 'cargo run --release':
344 sse_avx_stalls:u
1,321682733 seconds time elapsed
1,213303000 seconds user
0,104931000 seconds sys
The culprit seems to be SSE-AVX stalls. When looking at the assembly of the slow function with target-cpu set (Compiler Explorer: https://godbolt.org/z/69TxxzG4T). there is a AVX instruction before the SSE4a instruction "exrtq" an Amd specific instruction. There isn't a zveroupper between both instructions. This should be the causes of the SSE-AVX-stall when I'm not mistaken.
example::slow:
vmovdqu ymm0, ymmword ptr [rsi] // AVX
vmovq xmm1, rdi
extrq xmm1, 56, 0 // SSE4a
vmovq rax, xmm1
vpslld ymm0, ymm0, 5
vmovdqu ymmword ptr [rsi], ymm0
vzeroupper
ret
Meta:
I'm running Fedora:
$ rustc --version --verbose
rustc 1.75.0 (82e1608df 2023-12-21)
binary: rustc
commit-hash: 82e1608dfa6e0b5569232559e3d385fea5a93112
commit-date: 2023-12-21
host: x86_64-unknown-linux-gnu
release: 1.75.0
LLVM version: 17.0.6
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Rust reproducer with and without RUSTFLAGS="-C target-cpu=znver2", then compare the generated assembly shown in the issue and the sse_avx_stalls measurements. Investigate the compiler or LLVM code-generation path responsible for mixing AVX and SSE4a instructions; done means the cause is confirmed and a validated compiler change or regression test addresses the stall.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100