Live data from Hacker News

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

greyblake.com

11–20 of 124 posts

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

#11
post #3

Great explanation of why a branchless approach results in such a speed up. I've never really had to deal with performance optimization at this level. Generally it's probably best not to get too involved letting the CPU black box do its thing. I do wonder, would the performance characteristics of branchless vs branching be consistent across different CPUs/architectures? If you had a CPU that wasn't trying to be fancy…

Another recent story from github about case folding as part of code search, the simple version of the code had a couple of ifs, and the branchless version was actually slower.

They have a stupendously fast version and it is also branchless, but it just required more than branchless alone.

I'm fuzzy on the details but I think one of the ifs was an early exit, and without that the loop does a memory assignment on every byte instead of skipping most.

The really fast version was also vectorized. The branchless makes it possible to vectorize, but it was the vectorization that actually made it fast.

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

#12

This article is 100% AI written. The data was interesting, the commentary overly verbose and hard to gain useful insights from.

idk why this is getting downvoted, I also got this sense, plugged it into Pangram and indeed, 80% AI-written score.

I guess that's fine, but after awhile I get a spidey-sense reading something that feels like a Claude session.

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

#13
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_64::*;
    
        let mut out = vec![0.0; input.len()]; 
        let mut n = 0usize;
    
        let (head, tail) = input.as_chunks::();
    
        for chunk in head {
            unsafe {
                let p = _mm512_loadu_pd(chunk.as_ptr());
                let m = _mm512_cmpnle_pd_mask(p, _mm512_set1_pd(threshold));
        
                let compress = _mm512_maskz_compress_pd(m, p); 
                _mm512_storeu_pd(out.as_mut_ptr().wrapping_add(n), compress);
                n += m.count_ones() as usize;
            }   
        }   
    
        for &x in tail {
            out[n] = x;
            n += (x > threshold) as usize;
        }   
        out.truncate(n);
        out 
    }
For me it's about 25% less time than the branchless version with 1,000,000 elements, and 60% less with 10,000 elements where memory bandwidth effects are less relevant.

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

#15
post #3

Great explanation of why a branchless approach results in such a speed up. I've never really had to deal with performance optimization at this level. Generally it's probably best not to get too involved letting the CPU black box do its thing. I do wonder, would the performance characteristics of branchless vs branching be consistent across different CPUs/architectures? If you had a CPU that wasn't trying to be fancy…

Virtually every CPU has branch prediction, going back to at least the original Pentium (1993), maybe earlier. If you're running on a very old CPU, yes, the regular algo should be faster.

I think the Pentium is more or less the first microprocessor with branch prediction. Certainly the most mainstream.

PowerPC 601 arrived at more or less the same time, and the Alpha 21064 was a year earlier. There were a few minicomputers and mainframes before that with branch predictors.

Arguably the 486 could have done with a branch predictor (even a single entry loop predictor would have helped), and maybe the 386 too. But microcoded CISC designs didn't benefit much from predictors because they have multiple cycles to work it out.

And RISC cpus were in their "branch delay slots are awesome" phase throughout most of the 80s. With a bit of trickery (very simple branch conditions and a 2 phase clock), your classic 5-stage MIPS design can fully hide all branches with just a single branch delay slot, so they were a little slow to adopt predictors.

I get the impression that CPU designers in the 80s and early 90s massively underestimated just how beneficial even a small predictor can be.

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

#16
This problem is called stream compaction and there is a wealth of research on it. The best methods use prefix scan. They first efficiently compute the index in the output array of each element that satisfies the predicate and then they gather them in one linear operation.

Also, I can tell that you are a good writer. You didn't need the LLM to "polish" your text.

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

#17
post #7
post #4

Would PGO figure this out?

They could. but.... running PGO is just too much pain. We can't do it "incrementally", can we? How about combining with LTO? edit: I was thinking profiling individual module on a test driver and link them after PGO

I don't know if an optimization is allowed to "invent" a write, but I would be surprised if an optimizer goes that far because I have to believe that the number of cases where more writes improve performance are pretty slim.

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

#18

This article is 100% AI written. The data was interesting, the commentary overly verbose and hard to gain useful insights from.

I'm apparently not good at spotting it. I was put off by the overly dramatic presentation. It gets tiring that the author apparently finds this more exciting than I do, and writes like it's enthralling. I just assumed it was an excess of enthusiasm or the first experience with this kind of thing. If it's AI, I'm way behind the game noticing it.

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

#20
post #12

This article is 100% AI written. The data was interesting, the commentary overly verbose and hard to gain useful insights from.

idk why this is getting downvoted, I also got this sense, plugged it into Pangram and indeed, 80% AI-written score. I guess that's fine, but after awhile I get a spidey-sense reading something that feels like a Claude session.

[flagged]
Post reply on HN