C++ 防止GCC在使用-mavx和-mfma编译时自动使用AVX和FMA指令

C++ 防止GCC在使用-mavx和-mfma编译时自动使用AVX和FMA指令,c++,gcc,vectorization,avx,fma,C++,Gcc,Vectorization,Avx,Fma,如何使用AVX和FMA指令禁用自动矢量化?我仍然希望编译器自动使用SSE和SSE2,而不是FMA和AVX 我使用AVX的代码会检查它的可用性,但GCC在自动矢量化时不会这样做。因此,如果我使用-mfma进行编译,并在Haswell之前的任何CPU上运行代码,我会得到SIGILL。如何解决此问题?您需要将使用AVX的代码分离到一个单独的编译单元(换句话说,一个单独的.cpp文件),并仅使用-mfma或任何您想要的选项编译。通常,gcc将使用-march=native,因此它将为“您的处理器”编译,

如何使用AVX和FMA指令禁用自动矢量化?我仍然希望编译器自动使用SSE和SSE2,而不是FMA和AVX


我使用AVX的代码会检查它的可用性,但GCC在自动矢量化时不会这样做。因此,如果我使用
-mfma
进行编译,并在Haswell之前的任何CPU上运行代码,我会得到
SIGILL
。如何解决此问题?

您需要将使用AVX的代码分离到一个单独的编译单元(换句话说,一个单独的.cpp文件),并仅使用
-mfma
或任何您想要的选项编译。通常,
gcc
将使用
-march=native
,因此它将为“您的处理器”编译,如果您想要通用代码,则需要使用
-march=x86_64
-march=core2
,或类似的东西

您要做的是为每个目标指令集编译不同的目标文件。然后创建一个cpu调度程序,它向CPUID请求可用的指令集,然后跳转到相应版本的函数

我已经在几个不同的问题和答案中描述了这一点


因此,如果我有一个使用AVX的模板类(所有代码都在头文件中),我就有麻烦了?是的,它必须写得非常好,以避免每次调用其中一个函数时检查是否有AVX而受到惩罚。你真的对它进行了基准测试吗?我对它进行了基准测试,与SSE2相比,加速比很小,但它确实存在。当然,我不会每次调用
cpuid
,只在启动时调用一次。你确定没有单独的选项来禁用自动矢量化吗?我确信
gcc
会根据它认为最好的方式选择它认为在你编译的体系结构上可行的“任何”指令。因此,如果有聪明的指令来解决特定的构造,它可能会使用AVX指令。即使您当前的版本没有这样做,也不能说当前版本+0.0.1作为某种改进没有这样做。您需要的是一个CPU调度程序。使用
-msse2
将代码编译成一个对象文件,并将
-mfma
编译成另一个对象文件,然后创建一个调度程序,询问CPUID哪些硬件可用,并将函数指针设置为指向SSE2或AVX/FMA版本@Zboson:Yep,这就是我所做的。最近的gcc允许您在不使用-mfma或-mavx的情况下使用intrinsic。还可以为每个函数指定目标。