Live data from Hacker News

Beating the compiler

roguelazer.com

1–10 of 46 posts

Re: Beating the compiler

#2
Of course, the next step is obvious - work out why the compiler didn't do a four way avx unroll, and then submit a bug fix to clang to make it do that. That way all of your future code benefits from your single micro-optimization.

It's also possible that you find out that if you enable --generate-for-haswell or some other arcane compiler flag, it'll do it for you.

Re: Beating the compiler

#3
The reason to use intrinsics and inline assembly (actually, the latter is pretty rare these days, intrinsics being much more common) isn't only about beating the compiler.

When you're relying on the compiler to vectorize, you run the risk of a subtle, innocuous change to the code breaking the vectorization -- and this will happen a lot. Also, when you target multiple compilers, it's very difficult to get reliable performance across all of them, unless you do the vectorizing yourself.

Not to mention, compilers tend to do great on simple test cases like these, but totally barf as soon as the loop becomes more complex (Try adding some conditionals to the loops some time... It's not that these loops can't be vectorized, it's just that the compiler doesn't know how).

To get the best performance out of vectorization, it's mostly about organizing the data so that it can be easily vectorized. If you've gone through this work, it's fairly pointless not to take the extra effort to guarantee that you're getting the performance you expect.

Re: Beating the compiler

#4

Of course, the next step is obvious - work out why the compiler didn't do a four way avx unroll, and then submit a bug fix to clang to make it do that. That way all of your future code benefits from your single micro-optimization. It's also possible that you find out that if you enable --generate-for-haswell or some other arcane compiler flag, it'll do it for you.

All the author had to to was to add '-march=native' or '-march=core-avx2' to the compiler command line: http://goo.gl/H4f62I

Re: Beating the compiler

#5
Er. Author missed a crucial point of "just" using PyPy: for me it's over 24x speedup over standard python (if you run it enough times for JIT to warmup). Know your tools

Re: Beating the compiler

#6
post #3

The reason to use intrinsics and inline assembly (actually, the latter is pretty rare these days, intrinsics being much more common) isn't only about beating the compiler. When you're relying on the compiler to vectorize, you run the risk of a subtle, innocuous change to the code breaking the vectorization -- and this will happen a lot. Also, when you target multiple compilers, it's very difficult to get reliable per…

Rather than inline ASM, wouldn't it be better to have a maker that says "error if this can't be vectorised"? Something analogous to Scala's @tailrec

Re: Beating the compiler

#7
Note that the Python code is not limited to 32 bits and will automatically promote to bignum (aka long in py27).

    >>> l=[0xffffffff, 17]
    >>> sum(l) 
    4294967312
C based code will silently overflow/truncate, giving 16 in the example above. The author handwaved all this away, but it does show the usual tradeoffs between right/robust answers and fast answers.

Re: Beating the compiler

#9
post #4

Of course, the next step is obvious - work out why the compiler didn't do a four way avx unroll, and then submit a bug fix to clang to make it do that. That way all of your future code benefits from your single micro-optimization. It's also possible that you find out that if you enable --generate-for-haswell or some other arcane compiler flag, it'll do it for you.

All the author had to to was to add '-march=native' or '-march=core-avx2' to the compiler command line: http://goo.gl/H4f62I

Clang 3.7.0 (experimental) + -march=skylake gives you AVX512. zmm all the way, baby! 256 bytes processed in the inner loop!
Post reply on HN