within configuration.nix would enable CPU optimization for the whole system. It however isn’t the case anymore, gcc.arch and gcc.tune have been, from as far as I can tell, discontinued.
How would one set CPU flags for the C compiler within NixOS 22.11? From reading about it I think
nixpkgs.localSystem = {
cpu = "cpufamily";
system = "x86_64-linux";
};
}
Would work but I can’t quite tell.
Can you please confirm the information I have found?
With these flags the build did start to run, but from what I could see with ps none of the invocations of gcc actually had the march or mtune flags set as I’d expect. I interrupted the build and have given up on this for the time being.
I would be very interested to hear if you figure out a solution to this, especially if you get the micro-architecture feature level build working.
Don’t you also either need to set crossSystem? I’m not on the same architecture, but this probably is working for me on zen3. There was a reddit post about this here.
I don’t know if -march=$YOURARCH is ABI incompatible with not having extra instruction sets enabled? That’s what the reddit post says, but I can’t think what the incompatibility would be.
The “chicken and egg” problem mentioned in the reddit post is tricky. The first time you compile the system on an architecture without-march=$YOURARCH, your localSystem is x86_64 without the -march=YOURARCH, but once you’ve nixos-switched to the config with -march=$YOURARCH, then you need to build your system config with-march=$YOURARCH set for both crossSystem and localSystem. (same line of reasoning applies to tune)
But does this work? I have to recompile the world every time I upgrade, so I think so? As a case study I checked out htop, and built it from source with and without -march=native. Then, I ran elfx86exts over it. The result without-march=native is:
File format and CPU architecture: Elf, X86_64
MODE64 (call)
CMOV (cmovge)
SSE2 (movd)
SSE1 (movups)
BMI (tzcnt)
Instruction set extensions used: BMI, CMOV, MODE64, SSE1, SSE2
CPU Generation: Haswell
And with -march=native:
File format and CPU architecture: Elf, X86_64
MODE64 (call)
CMOV (cmovge)
AVX (vmovd)
AVX2 (vinserti128)
NOVLX (vpxor)
BMI2 (shlx)
BMI (tzcnt)
Instruction set extensions used: AVX, AVX2, BMI, BMI2, CMOV, MODE64, NOVLX
CPU Generation: Unknown
And this matches what is in the nix store for htop built with -march=znver3 in my system config. So, I think it’s safe to say the -march=znver3 is being applied.
An interesting follow up question (that maybe someone else knows the answer to?) is how does one add LTO globally? I haven’t been able to figure out how to even add -flto globally to CFLAGS. This documentation is broken. And there doesn’t seem to be a place to append to LDFLAGS AFAICT.