Live data from Hacker News

AVX-512: First Impressions on Performance and Programmability

shihab-shahriar.github.io

51–54 of 54 posts

Re: AVX-512: First Impressions on Performance and Programmability

#51
post #42

Earlier quoted context omitted.

Even with AVX512, memory arguments used in most instructions (those that are not explicitly unaligned loads) need to be aligned, no? E.g., for vaddps zmm0, zmm0, [rdi] (saving a register and an instruction over vmovups + vaddps reg, reg, reg), rdi must be suitably aligned. Apart from that, there indeed hasn't been a real unaligned (non-atomic) penalty on Intel since Nehalem or something. Although there definitely is…

AVX doesn't require alignment of any memory operands, with the exception of the specific load aligned instruction. So you/the compiler are free to use the reg,mem form interchangibly with unaligned data. The penalty on modern machines is an extra cycle of latency and, when crossing a cacheline, half the throughput (AVX512 always crosses a cacheline since they are cacheline sized!). These are pretty mild penalties giv…

> AVX doesn't require alignment of any memory operands, with the exception of the specific load aligned instruction.

Hah, TIL. Too used to SSE, I guess. (My main target platform is, unfortunately, still limited to SSE3, not even SSSE3.)

Re: AVX-512: First Impressions on Performance and Programmability

#52
post #2

What I get in these article is that the original intent on C language stands true. Use C as a common platform denominator without crazy optimizations (like tcc). If you need performance, specialize, C gives you the tools to call assembly (or use compiler some intrinsic or even inline assembly). Complex compiler doing crazy optimizations, in my opinion, is not worth it.

> Complex compiler doing crazy optimizations, in my opinion, is not worth it. For these optimisations that are in the back-end, they are used for other languages that can be higher-level or that cannot drop to assembler as easily. C is just one of the front-ends of modern compiler suites.

Some of them even give you access to this stuff. C# has Vector which picks implementations of various operations based on the current CPU's capabilities. But they also let you have complete control if you want by providing functions in the System.Runtime.Instrinsics namespace.

Re: AVX-512: First Impressions on Performance and Programmability

#53

Earlier quoted context omitted.

> I am not sure if there is a better way to find the fastest code path besides "measure on the target system", which of course comes with its own challenges. Yeah, and it's incredibly frustrating because there is almost zero theory on how to write performant code. Will caching things in memory be faster than re-requesting them over network? Who knows! Sometimes it won't! But you can't predict what those times will be…

You do have NUMA to control memory placement, it's not that easy to use though: https://blog.rwth-aachen.de/itc-events/files/2021/02/13-open...

Well, we didn't, for obvious reasons, patch JVM to manually finagle with physical memory allocation — which it probably wouldn't be able to do anyway, being run in a container.

Re: AVX-512: First Impressions on Performance and Programmability

#54
post #46

A few gentle points: (a) You mention that the NVidia docs push people to use libraries, etc. to really get high performance CUDA kernels, rather than writing them themselves. My argument would be that SIMD is exactly the same - they're something really that are perfect if you're writing a BLAS implementation but are too low level for most developers thinking about a problem to make use of. (b) You show a problem wher…

Hi, thanks for reading. Re (b) I'm curious what that middle ground is. Is there any simple refactor to help GCC to get rid of this `if`? (Note, ISPC did fine here) (c) Just to be clear, all the codes in benchmark figures (baseline and SIMD) were compiled with fast-math flags. Regarding (a), one of the points I wanted to get across was that it didn't feel that complicated to program in the end as I had thought. Portin…

The typical way would be to unroll the inner loop manually; often you can get away with:

    for (int i = 0; i 
but failing the compiler optimising that you can do it more like:

    for(int i = 0; i 
That's effectively what you're doing anyway in the SIMD code, but it keeps it more readable for mere mortals, and because you can define SIMD_WIDTH as a constant, it's also slightly easier to change if a new instruction set comes along; you're not maintaining multiple kernels.
Post reply on HN