Live data from Hacker News

Everyone should know SIMD

mitchellh.com

201–210 of 263 posts

Re: Everyone should know SIMD

#201

Good article! I just wouldn't start off with bold sentences as > SIMD can be simple to understand and > writing SIMD is just about as easy as a for loop and then the first example requires 12 lines to replace one line of scalar code. Be honest and say SIMD is hard but the results are worth it! (Another nitpick: if this article is for newbies, don't use SIMD-only words and concpts before explaining them. Step 5 is goo…

Around 1990 I had the fortune to learn Parallel-C - a language that was designed during the Transputer hype and was essentially C extended by a few features to support easy parallel programming. My favourite feature was par( ; ; ) essentially a for loop that will be auto-parallelized by the compiler - some boundary conditions apply.

I believe this still lives on through XMOS. I remember (fondly) doing this on one of their chips mid-to-late 2000's doing a bit of audio processing. Think it might have even been designed by the original transputer folks.

Re: Everyone should know SIMD

#202

Earlier quoted context omitted.

I have no idea why you're being downvoted. HN has a fetish for SIMD, but if you are hand-rolling SIMD and you aren't writing an explicit acceleration library, you're doing it wrong. Like, 100% of the time. Every modern language has a vectorization optimizing compiler, and through some fairly straightforward techniques this is automagic. And contrary to the various replies, unless you screwed something up compilers ar…

Compilers are really good but really good is not actually that useful in cases where you need SIMD

I mean, utter bullshit. If you "need SIMD" you know exactly the programming pattern to guarantee SIMD from the compiler. And the single and only people who "need SIMD" know these rules. It is only the hobbyist "SIMD is neat" community that upvotes these ridiculous articles.

Re: Everyone should know SIMD

#205
post #66

Earlier quoted context omitted.

> what can be fast I think this doesn't get talked about enough. If your input is a big run of data that is being checked/transformed in one shot, it works well. But, if you're likely to have to make a decision on several bytes of the input, SIMD will be the same or slower than the scalar method. It's not a magic "go fast" button.

That is not necessarily true. simdjson exists. But it's far from simple. I have been told SIMD is good for data-parallel loops, like the GPU is, and that is true, but it can also be used piecemeal, unlike the GPU. Because it is just the CPU, you can read 32 unaligned bytes, scan for the index of the first space, and take a branch based on that.

> That is not necessarily true. simdjson exists.

I am speaking exactly of simdjson. If you look closely, you'll see that the high performance is really only achieved by skipping over large chunks of the input data. Which is great, if your use case is operating on a subset of data. But, if the application really needs to process every piece of the entire input, there's no performance win.

Think about it, JSON structure is almost entirely made up of single bytes ({ } [ ] , : "). If you're not skipping over stuff, you're not going to get away from having to examine those bytes and branch on them. For something like `{"a":1,"b":2}`, the SIMD scan has a bunch of overhead to find the interesting parts and then you go back and practically have to reprocess every single byte.

Re: Everyone should know SIMD

#206
I recommend starting with SWAR [1] before SIMD. Our registers are typically 64 bits, and one can try out SIMD patterns without taking a dependency on particular hardware.

This will only be effective if the data you’re working on is smaller than 64 bits. If you’re working with bytes, for example, you might get 8x parallelism.

[1] https://en.wikipedia.org/wiki/SWAR

Re: Everyone should know SIMD

#207

Earlier quoted context omitted.

> Vectors (in C++) at least aren't necessarily the best fit either I'm not sure if you use a different allocation strategy or if you're advocating allocating as much as possible up-front, but I'm curious if you have any thoughts on this: I always end up using (Rust) vectors despite looking at a bunch of slab/arena allocation libraries. Preferably I'd know how much memory I need up front, but barring that I see three…

A fourth alternative, in 64-bit systems, is to reserve a stupidly large chunk of memory up front with `mmap()` or equivalent (`malloc()` actually should work about as well). That way you guarantee that any extension will happen in place. There’s a limit to how much you can reserve, but since that limit is much higher than what you can actually use, you can make quite a few of those reservation before you run out of a…

In Rust at least, most things have a with_capacity(n) constructor to ensure there's space for n elements (or n bytes, in the case of strings). I suppose there's no getting around the fact that if your collection has no known bounds, you'll have to do bounds checking + potential reallocation in the hot (push) path or risk having your program SIGSEGV.

https://doc.rust-lang.org/std/?search=with_capacity

Re: Everyone should know SIMD

#208

Earlier quoted context omitted.

True on all counts. Not sure why you're getting downvoted.

It’s a bit weird because it is one of the better HN comments I read in the last days.

Thanks for the kind compliment : )

I try to ask myself whether things I write are (1) writing and (2) reading before writing. Sometimes that works.

Re: Everyone should know SIMD

#209
post #194

Earlier quoted context omitted.

Yep, I avoid saying the word simple almost entirely - its straight forward to get to the top of a mountain, it might still be incredibly arduous.

Simple Network Management Protocol Simple Mail Transfer Protocol Lightweight Directory Access Protocol Sometimes I think the RFC editors are trolling us.

Well. I thought so as well about LDAP. Until one day I had to interact with the kind of technology LDAP was built to replace...

Re: Everyone should know SIMD

#210
post #25

Earlier quoted context omitted.

> some builtins purport to work on simd vectors but actually just unpack the vectors and do their work per-element (e.g. running `@sin()` on a `@Vector(4, f32)` will unpack the vector, run `@sin()` 4 times, and then pack it back into a vector). this is reasonable because there isn't really a generalizable "good way" to unroll trig functions for simd. if you really care about speed youre better off implementing to the…

i don't disagree – i have my own internal vector lib of approximations and whatnot for various tradeoffs of precision and speed, so i just use those. it's just that zig has a pretty strong stance of "no unexpected/obscured code execution" so it was surprising to see a vector-capable function that was just a bunch of scalar functions in a trench coat. maybe functions that don't actually support actual vector execution…

> maybe functions that don't actually support actual vector execution just shouldn't work on vector arguments.

i think that's reasonable.

Post reply on HN