Ricing it up

One of the reasons that I find myself going back to Gentoo is that you compile the entire system for your hardware which, in theory, leads to the best performance possible. So the first task that I undertook when switching the NUC over to it was to figure out what compile options ClearLinux uses. Once I had figured those settings out, I then decided to use LTO optimization for all packages that support it. However, I didn’t want to use the LTO overlay.

After doing a lot of digging around and some experimentation, I finally settled on the following configuration:

# /etc/portage/make.conf
CFLAGS="-march=skylake -mtune=skylake -O3 -pipe -w -falign-functions=32"
CFLAGS="${CFLAGS} -fgraphite-identity -floop-nest-optimize -floop-parallelize-all"
CFLAGS="${CFLAGS} -flto=auto -flto-partition=one -fuse-linker-plugin"
CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sse sse2 sse3 sse4_1 sse4_2 ssse3"
LDFLAGS="-Wl,-O3 -Wl,--sort-common -Wl,--as-needed"

As you can see, I start with a base CFLAGS, then I add Graphite optimizations, and finally the LTO optimizations are added. Occasionally, LTO will cause undefined symbols and the build will fails, so for that I have:

# /etc/portage/env/cflags-ffat-lto-objects
CFLAGS = "${CFLAGS} -ffat-lto-objects"

And occasionally a package just won’t compile with LTO, so that I use:

# /etc/portage/env/cflags-fno-lto
CFLAGS="-march=skylake -mtune=skylake -O3 -pipe -w -falign-functions=32"
CFLAGS="${CFLAGS} -fgraphite-identity -floop-nest-optimize -floop-parallelize-all"

Whenever I run into a package that has compile issues, I simply create a file for it in /etc/portage/package.env that looks like:

package_atom cflags-ffat-lto-objects


package_atom cflags-fno-lto

This little setup has, so far, worked like a charm for me. Out of the 63 packages in my world file, only 12 need an env file to compile properly on my ~amd64 install. And everything feels snappy during my day to day. I’m quite pleased.