Live data from Hacker News

New optimizations for X86 in upcoming GCC 5.0

software.intel.com

21–30 of 41 posts

Re: New optimizations for X86 in upcoming GCC 5.0

#21
post #19
post #8

I'm so glad to see auto-vectorization happening more and more often. However, I wonder whether a language that had built-in support for primitive floating-point vector types (e.g., GLSL's vec3, vec4, mat3, mat4) could help the compiler with performing these sorts of optimizations.

I spent a lot of the past month improving the RenderScript (Android data-parallel compute, using C99 plus vectors) codegen to better work with the LLVM vectorizers, so I have a fair amount of experience with this exact question. The vector types help in some ways--if you can use only vectors and do arithmetic on entire vectors only the SIMD codegen already works great--but they don't really help more than an intellig…

Fabulous comment, please keep posting more and sharing your knowledge/experience. And thanks for the re-reminder of 'ispc'. A couple tiny additions:

While loading each element with an individual 32-bit load usually negates the advantage of vectorization, if you are using 8-bit data, doing a single vector load and shuffling bytes within a 128-bit vector is really fast with AVX. And shuffling double- and quad-words within 256-bits with AVX2 can be a useful alternative even if you have to do it twice and combine. But even better is to rearrange your data layout to match the operations you are going to be doing.

AVX2 doesn't actually offer scatter support, although AVX-512 will. And AVX2 gather on Haswell normally isn't any faster than multiple individual loads, although it's no worse and the the expectation is that future generations will improve on this significantly. Also worth pointing out is that 256-bit YMM vectors are conceptually split in two, so apart from the slightly slower 32/64/128-bit permute instructions, it's not possible to move data from one 128-bit 'lane' to the other.

Re: New optimizations for X86 in upcoming GCC 5.0

#22
Only loosely related, but I'm curious: What compiler optimizations have the biggest impact on scientific / floating point computation? Integer (audio/image) ops? With modern CPUs performing speculative execution, register renaming, and all the other magic they do, the CPU is acting like an optimizer in its own right. x64 is mostly just a byte code that gets JIT compiled at runtime. I'd be interested in seeing how much specific optimizations (including classic ones) contribute to speeding things up.

Re: New optimizations for X86 in upcoming GCC 5.0

#23

Here is a more general list of gcc 5 changes https://gcc.gnu.org/gcc-5/changes.html EDIT was looking at this for __builtin_mul_overflow which apparently are in clang already, for testing overflow of arbitrary types.

> ... gcc 5 changes ...

I'm disappointed it says literally nothing about auto-vectorization. I had to do an incredible amount of hand-holding to get GFortran 4.9's auto-vectorization to work worth anything. A few experiments with C code showed that GCC 4.9 was just plain bad at it compared to even Clang, much less ICC. If I work on that project again, I'll probably look into getting DragonEgg [1] to work so I can get decent optimization without contorting the code as much.

The OP mentions an important case with loads and stores of 3D data, but GCC needs to up its game in more ways than that.

[1] http://dragonegg.llvm.org/

Re: New optimizations for X86 in upcoming GCC 5.0

#24

Here is a more general list of gcc 5 changes https://gcc.gnu.org/gcc-5/changes.html EDIT was looking at this for __builtin_mul_overflow which apparently are in clang already, for testing overflow of arbitrary types.

I'm guessing from the libstdc++ change log that GCC 5.x will instigate an ABI break?

Re: New optimizations for X86 in upcoming GCC 5.0

#25
post #20
post #16

Does anyone know if -O3 (or -O2?) -march=native should be enough to get reasonable optimization for running on the same cpu as the gcc host? Or are one better off tweaking options manually (note, I know that knowing the details of how gcc works will always be better than not -- I'm just wondering if -march=native is currently considered stable/"good enough" from reasonable value of "enough" ;-)

I think yes. A couple weeks ago I tested compilation for a project on Haswell and Sandy Bridge using various recent versions of CLang, GCC, and ICC to determine whether it was safe to use just "-O3 -march=native" in combination with "#include " instead of more specific versions. While my testing was far from rigorous, my conclusion was that this is now sufficient and acceptable to get appropriate platform-specific SI…

Thank you both, and especially for the mention of x86intrin.h ... I wasn't aware of that.

Re: New optimizations for X86 in upcoming GCC 5.0

#26
post #21
post #19

Earlier quoted context omitted.

I spent a lot of the past month improving the RenderScript (Android data-parallel compute, using C99 plus vectors) codegen to better work with the LLVM vectorizers, so I have a fair amount of experience with this exact question. The vector types help in some ways--if you can use only vectors and do arithmetic on entire vectors only the SIMD codegen already works great--but they don't really help more than an intellig…

Fabulous comment, please keep posting more and sharing your knowledge/experience. And thanks for the re-reminder of 'ispc'. A couple tiny additions: While loading each element with an individual 32-bit load usually negates the advantage of vectorization, if you are using 8-bit data, doing a single vector load and shuffling bytes within a 128-bit vector is really fast with AVX. And shuffling double- and quad-words wit…

sorry, the desktop Intel SIMD ISAs are generally not something I use on a day-to-day basis, so I get them mixed up a lot. (LRBni was the last one I looked at for any serious length of time.)

Re: New optimizations for X86 in upcoming GCC 5.0

#27
post #15
post #6

Competition (with clang) is good.

People contribute to compilers because they need features or performance improvements, not "to kick that other compiler's ass". Sometimes (as here) contributions are from CPU vendors who want to make certain that compilers show off the features of their new hardware. There were tons of great performance impovements in every new version of GCC before clang, and there continue to be today. You just can't model an open…

GCC was explicitly against a plug-in architecture for political reasons, but did grow one when llvm showed up

Re: New optimizations for X86 in upcoming GCC 5.0

#28
post #16

Does anyone know if -O3 (or -O2?) -march=native should be enough to get reasonable optimization for running on the same cpu as the gcc host? Or are one better off tweaking options manually (note, I know that knowing the details of how gcc works will always be better than not -- I'm just wondering if -march=native is currently considered stable/"good enough" from reasonable value of "enough" ;-)

I remember that -flto sometimes adds few %'s to overall speed. If you are doing a lot of floating point math you can check various modes. First try is always -Ofast which turns on -ffast-math flag. From the gcc page:

    -ffast-math
    Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and -fcx-limited-range.

    This option causes the preprocessor macro __FAST_MATH__ to be defined.

    This option is not turned on by any -O option besides -Ofast since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.
I also remember that gcc started producing significantly faster code for my projects at around 4.7 or 4.8 version (can't remember which one).

Re: New optimizations for X86 in upcoming GCC 5.0

#29
post #15
post #6

Competition (with clang) is good.

People contribute to compilers because they need features or performance improvements, not "to kick that other compiler's ass". Sometimes (as here) contributions are from CPU vendors who want to make certain that compilers show off the features of their new hardware. There were tons of great performance impovements in every new version of GCC before clang, and there continue to be today. You just can't model an open…

I disagree, competition itself was good for GCC.

Stallman's reaction¹ to LLVM was noisy and possibly childish, but it gave the FSF another important goal: not only should it supply a "libre" compiler but it should also be worth using over the first alternative that comes along. That second goal is a moving target, unlike the first, and it supplies a real motivation to make the best compiler they can.

1. http://www.phoronix.com/scan.php?page=news_item&px=MTU4MjA

Re: New optimizations for X86 in upcoming GCC 5.0

#30
post #13

Earlier quoted context omitted.

Where did you get 24 from? It's about vectorizing loads of 3 elements. The elements don't have to be 8-bit. The second example uses floats.

Yeah, but 24-bit values (RBG) are what you'd find in video and gaming applications.

Games, at least what I've seen, usually just don't use 3x(8|16|32) bits per pixel, if it's not needed as alpha. It's pretty rare to pack 24/48/96-bit pixels in memory. Traditionally, unaligned loads are just not worth it.

Sometimes packed formats were worth it. I remember doing RLE schemes for fast "alpha blending" (anti-aliased blitting really!) back in 2000 or so, before MMX or GPUs were common. The scheme I used had three different types of run lengths. Completely transparent, pre-multiplied alpha blended and completely opaque. 16-bit pre-multiplied values were in memory in 32-bit format like this: URGBU00A. Groups of 5 bits, except U denotes unused single bit. Frame buffer in RAM was in 15 bit format, 0RRRRRGGGGGBBBBB. With this scheme, alpha-blending needed totally just one multiply per pixel [1], compared to three with usual pre-multiplied alpha or six with normal alpha without pre-multiplication.

[1]: Frame buffer pixels were masked and shifted into 000000GGGGG000000RRRRR00000BBBBB, multiplied by A and shifted back in place. Because all values were 5 bit entities, no overflow (overlap) could occur in multiply, thus one multiply yielded 3 multiplied frame buffer pixel values, for R, G and B!

Post reply on HN