Branchfree
branchfree.org · Personal blog · on HN since 2018
Branchfree is a blog on SIMD programming, bit-level tricks, and fast parsing and automata, with posts on x86 and ARM instructions.
What HN saysCommenters cite it as a good source on SIMD topics, including its ARM Neon movemask substitutes and its taxonomy of SIMD usage.
26HN people shared it
13linked it in comments
22stories submitted
479story points
4 months agolast shared
2018people per year2026
Most-shared posts
- 1A (Draft) Taxonomy of SIMD Usage5 people · 17 points · first shared 2024 · 4 comments on HN
- 2Question: Is matching *fixed* regexes with Back-references in P?5 people · 4 points · first shared 2019 · discussion on HN
- 3Why Ice Lake is Important – a bit-basher’s perspective4 people · 112 points · first shared 2019 · 41 comments on HN
- 4Show HN: Sheng, a Small but Fast Deterministic Finite Automaton4 people · 7 points · first shared 2018 · discussion on HN
- 5Code Fragment: Finding quote pairs with carry-less multiply (PCLMULQDQ)4 people · 5 points · first shared 2019 · discussion on HN
- 6Bits to indexes in BMI2 and AVX-5123 people · 5 points · first shared 2018 · discussion on HN
- 7Paper: Parsing Gigabytes of JSON per Second3 people · 3 points · first shared 2019 · discussion on HN
- 8Fitting My Head Through the ARM Holes (Substitutes for SSE's Pmovmskb on Neon)3 people · 1 points · first shared 2019 · discussion on HN
- 9Homepage3 people · first shared 2018
- 10Some opinions about “algorithms startups”, from a sample size of approximately 12 people · 6 points · first shared 2018 · 1 comments on HN
- 11The Environment Will Be Saved If We Just Avoid Doing Icky Things2 people · 4 points · first shared 2024 · 1 comments on HN
- 12An Intel Programmer Jumps over Wall: First Impressions of ARM SIMD Programming1 people · 167 points · first shared 2019 · 38 comments on HN
- 13Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs1 people · 148 points · first shared 2019 · 36 comments on HN
- 14Smh the swiss army chainsaw of shuffle based matching sequences1 people · first shared 2019
What HN people wrote when they linked it
camel-cdr · 2023-06-07
I found the following article about the topic really good: https://branchfree.org/2019/04/01/fitting-my-head-through-the-arm-hole…
In my experience using a 512 wide movemask (to uint64_t) is the fastest on both x86 and arm64.
With rvv you don't really what to go from a vector mask to a general purpose non vector register, because the vector length may vary. But I found it really useful that vector masks are always packed into v0. So even with LMUL=8, you can just to a vmseq, switch to LMUL=1 and use vfirst & vmsif & vmandn to iterate through all indices. (Alternatively vfirst & vmsof & vmclr would also work, I'm not sure which one would be faster)
glangdale · 2021-04-22
PMOVMSKB is a great instruction, and 3c understates how cheap it is - if you have a throughput problem (rather than a latency problem) it's even more efficient relative to the ARM equivalent.
I have a blog post about coping strategies for working around the absence of PMOVMSKB on NEON:
https://branchfree.org/2019/04/01/fitting-my-head-through-the-arm-hole…
We used these techniques in simdjson (which I presume still uses them; the code has changed considerably since I built this): https://github.com/simdjson/simdjson
The best techniques for mitigating the absence of PMOVMSKB require that you use LD4, which results in interleaved inputs. This can sometimes make things easier, sometimes harder for your underlying lexing algorithm - sadly, it's not a 1:1 transformation of the original x86 code.
kristianp · 2020-12-14
In this case, Dr Lemire is using software he co-wrote to test the performance of the M1. It makes sense that he'd be focussing on that software (Simdjson) which wrings as mich speed out of the processor as possible by using vector instructions and avoiding branches. His coauthors blog iirc is even called https://branchfree.org, to indicate the importance of avoiding branch mispredictions to keep the cpu foing quickly.
burntsushi · 2020-02-25
Nope. That still supports backreferences, and resolving backreferences is an NP-complete problem.[1] And I don't see anything in that paper that addresses that. Note that there may be some versions of the problem that maybe aren't NP-complete[2], but again, not addressed by that paper.
Besides, that paper was published 12 years ago. Where is the productionized version of it? Or are you suggesting the the OP go spend a few years writing a regex eninge? :-) Doesn't seem like a particularly practical suggestion.
[1] - https://perl.plover.com/NPC/NPC-3SAT.html
[2] - https://branchfree.org/2019/04/04/question-is-matching-fixed-regexes-w…
pkhuong · 2025-04-24
There's more to SIMD than BLAS. https://branchfree.org/2024/06/09/a-draft-taxonomy-of-simd-usage/ .
mananaysiempre · 2025-01-27
jeffffff · 2023-06-30
there are only a handful of instructions that do interesting things beyond parallel versions of basic arithmetic and bitwise operations. https://branchfree.org/2019/05/29/why-ice-lake-is-important-a-bit-bash… provides a good overview of them.
mumumu · 2023-01-26
*avoid branches
The blog post I mentioned:
Paper: Parsing Gigabytes of JSON per Second
https://branchfree.org/2019/02/25/paper-parsing-gigabytes-of-json-per-…
Another related post from Lemire:
Ridiculously fast unicode (UTF-8) validation
https://lemire.me/blog/2020/10/20/ridiculously-fast-unicode-utf-8-vali…
Those algorithms are fast. But to put them in perspective. A single x86 CPU can write 64B per cycle. At 5GHz, the theorical maximum bandwidth is 320 GBps. IIRC, the read bandwidth is twice that.
There are others botlenecks, and is very hard to write code that writes at every cycle.
A interesting consequence, is that the theorical maximum bandwidth is logarithmical to the number of cycles. Again, talking about branchless streaming application.
henrydark · 2021-12-04
Langdale also has a state machine simd idea that can be used for the full csv transition table:
https://branchfree.org/2018/05/25/say-hello-to-my-little-friend-sheng-…
I implemented this at some point (the "noisy" version, in Langdale's words) and got a csv tokenizer that spent about 1.5 cycles per byte.
BeeOnRope · 2021-12-04
You can probably get another "few x" faster still:
https://branchfree.org/2019/03/06/code-fragment-finding-quote-pairs-wi…
Based on a cursory scan this is the same problem so Geoff's trick should be directly applicable.
The ideas are quite similar: using bit manipulation to detect the in and out regions. Geoff's trick does the "smearing" of the bits in a single SIMD "carryless multiply", plus some supporting stuff. It is constant time for an input word: there is no dependence on the number of bits. So it could be many times faster for inputs with very dense quotes.
For an actual implementation, you'd want to handle the case where you don't have any quotes at all or where they are very sparse, which is common to a lot of CSV with a fast path that bails out when it sees a quote (possibly to be be resumed later if there is again a quote-free run).
aliceryhl · 2020-08-11
There are fully correct JSON parsers you aren't going to beat, even if you implement a subset. [1]
[1]: https://branchfree.org/2019/02/25/paper-parsing-gigabytes-of-json-per-…
nkurz · 2019-01-06
Do you recall which machines VPCOMPRESSB works on? I think it's next generation Icelake? Or is it there already on Cannonlake? And along the same lines, is there a good general way of looking this up?
Coincidentally, searching for this, I found Geoff Langdale's blog post where in addition to describing VPCOMPRESSB as 'dynamiting the trout stream', he also describes something very close to zwegner's PEXT approach: https://branchfree.org/2018/05/22/bits-to-indexes-in-bmi2-and-avx-512/
zwegner · 2021-12-21
Yeah, I see how the quoting complications make CLMUL pretty hard to use (or just useless). I have a few ideas about how to deal with the quoting/escaping, and if I get some free time in the near future I'll try and code something up.
I've also pinged Geoff and Daniel on Twitter, linking your library: https://mobile.twitter.com/zwegner/status/1473400733525544973 ...maybe they'll have some ideas. (Geoff has mentioned that he had done some initial work on a simdcsv)
I'll also drop some more links that you might've already seen, but could be useful otherwise.
For removing double quotes, rather than memmove, you could use the "pack left" operation on vectors. There's a handful of ways to do this pre-AVX-512-VBMI2 (where the magical vcompressb instruction was added), like in these SO questions:
https://stackoverflow.com/questions/36932240/avx2-what-is-the-most-eff…
https://stackoverflow.com/questions/45506309/efficient-sse-shuffle-mas…
And for keeping the main lexer structure that ZSV uses now, but using a small DFA to maintain the lexer state, this other trick from Geoff might work: https://branchfree.org/2018/05/25/say-hello-to-my-little-friend-sheng-…