GCC compiler provides a set of builtins to test some processor features, like availability of certain instruction sets. But, according to this thread we also may know certain cpu features may be not enabled by OS. So the question is: do __builtin_cpu_supports
intrinsics also check if OS has enabled certain processor feature?
does gcc's __builtin_cpu_supports check for OS support?
Asked Answered
No.
I disabled AVX on my Skylake system by adding noxsave
to the Linux kernel boot options. When I do cat /proc/cpuinfo
AVX (and AVX2) no longer appear and when I run code with AVX instructions it crashes. This tells me that AVX has been disabled by the OS.
However, when I compile and run the following code
#include <stdio.h>
int main(void) {
__builtin_cpu_init();
printf("%d\n", __builtin_cpu_supports ("sse"));
printf("%d\n", __builtin_cpu_supports ("avx"));
}
it returns 8 and 512. This means that __builtin_cpu_supports
does not check to see if AVX was disabled by the OS.
This really shows that GCC does not check if OSXSAVE is defined. After that the OS needs to be tested as well https://mcmap.net/q/25180/-what-is-the-minimum-version-of-os-x-for-use-with-avx-avx2. –
Patellate
This should probably be considered a gcc bug; Usually you really want to know whether AVX is actually usable, not whether just the CPU supports it. If you really want to differentiate between supported by the CPU but not usable, that's when using CPUID manually should be needed. I assume most existing code that uses
__builtin_cpu_supports ("avx")
assumes that code compiled with -mavx
can run if it's true. –
Thermobarograph @PeterCordes, it should be considered a bug. I certainly expected it to check if AVX was enabled by the OS in my answer here. BTW, what is
xsave
and xgetbv
. Why are there two methods to disable AVX? I guess disabling xsave
is more restrictive. How do you disable AVX without disabling xsave
. –
Patellate You're asking how an OS in general could disable AVX support while still using one of the
xsave
* instructions to save SSE/FPU/MPX registers on context switches? I think an OS could still just use the instruction without setting the control-register bit that indicates that the OS promises to do that, so AVX instructions would still fault. IDK if Linux has an option to do that. Or maybe still set that bit, but not enable saving ymm upper halves with xsetbv
. xgetbv
is an instruction for reading extended control-registers.. –
Thermobarograph @PeterCordes, what I mean is why does
if ((xgetbv(0) & 6) != 6)
test for if AVX is enabled by the OS. –
Patellate That expression is testing 2 bits in extended control-register 0 to see if they're both set. I think those are the bits the OS has to set with
xsetbv
to promise that it will use xsave
to save ymm upper halves on context switches, so it's safe for the CPU to allow AVX instructions to execute. You can look up the exact meaning of those bits if you want. –
Thermobarograph @PeterCordes how can the OS block instructions? I mean I could see how things would crash in context switches but isn't it possible that you could use AVX for example only for reads which would not crash. –
Patellate
AVX instructions fault if those bits aren't set. AVX is just designed this way, so AVX-aware user-space programs on AVX-unaware kernels at worst fault with #UD (SIGILL) instead of silent data corruption. SSE has a similar control bit: the OS has to set a bit in a control register or else SSE instructions fault. You can see this bit as a promise to save/restore xmm regs. But Intel unfortunately didn't include a clean way for user-space to detect if the OS had set that bit. That was new with AVX. https://mcmap.net/q/16183/-which-versions-of-windows-support-require-which-cpu-multimedia-extensions-how-to-check-if-sse-or-avx-are-fully-usable –
Thermobarograph
Anyway, the point of all this is so silent data corruption on context switch is not a likely failure mode. That can generally only happen with an AVX-aware but buggy kernel. –
Thermobarograph
Yes, it does. There was a bug in GCC but it was fixed around GCC 8: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100
© 2022 - 2024 — McMap. All rights reserved.
__builtin_cpu_supports
and answer your question. – Patellatenoxsave
to the kernel options for Linux. – Patellate__builtin_cpu_supports
checks the OS. – Patellate