Live data from Hacker News

Branchless Rust: Making a Filter 4x Faster by Removing an If

greyblake.com

121–124 of 124 posts

Re: Branchless Rust: Making a Filter 4x Faster by Removing an If

#121
post #108

Nice post! You can do even a bit better if you're willing to use intrinsics. In particular this kind of operation is well-suited for compress-type operations, available as a first-class operation in at least AVX512, SVE and RVV; you can also emulate them reasonably quickly on NEON and AVX2. Here's an example, building on the OP's work: pub fn filter_compress(input: &[f64], threshold: f64) -> Vec { use std::arch::x86_…

This is interesting. So at a certain scale, CPU optimization becomes irrelevant because you're just waiting for new data to come in?

Memory access patterns are usually the main reason for low performance and should be optimized first because it's a great low hanging fruit (and usually the bigger problem is latency, not bandwidth).

And don't think of waiting for memory as making CPU optimizations irrelevant, but instead as an oppurtinity to hide more CPU operations in the remaining 'memory access gaps' (e.g. the CPU won't simply stop working when waiting for data to be loaded from memory, it can continue with other things that don't depend on that data).

Re: Branchless Rust: Making a Filter 4x Faster by Removing an If

#122
post #93
post #86

Earlier quoted context omitted.

Keep in mind it's UB to be: > Executing code compiled with target features that the current thread of execution does not support I.e. calling AVX512 on Neon architecture. You need to wrap it in target attributes to even dream of it being safe.

This particular UB is not one of the subtle cases. You will almost certainly get illegal instruction signals if you mess this up.

I'd say unwrap isn't a subtle case either. Yet people see examples and think - "This is the way!"

Re: Branchless Rust: Making a Filter 4x Faster by Removing an If

#123
post #74

Earlier quoted context omitted.

I disagree in the sense that you can rewrite the code to use the trick and also not allocate in advance. Nothing about the trick requires you to allocate up front: before writing to out[n] you can extend the vector if it’s out of bounds. Or, after incrementing n, do out.push(0).

You should try writing it out. Doing it without introducing another unpredictable branch is harder than it looks. I discussed this with a coworker earlier this week and the best they were able to come up with was for &x in input { out.push(x); n += (x > threshold) as usize; out.truncate(n); } which works but is ugly af imo.

Yep realized this after that my second solution (push a 0 if n is incremented) has the same branch prediction problem.

I think yours works. Alternatively in the loop:

    if out.len()  threshold) as usize;
In this case the if will be predicted well because it only triggers log(N) times, given how the std lib extends vectors.

Re: Branchless Rust: Making a Filter 4x Faster by Removing an If

#124

Earlier quoted context omitted.

I switch languages randomly.

What do Claude's tics look like in your other language? Do they carry over or does each language get its own weird rhetorical flourishes?

Hard to say for me... I use it for programming, but want it to not talk too much. So I've not many experiences with letting it write long texts...
Post reply on HN