GCC 12(MinGW 64)如何启用融合乘加(FMA)指令生成?
问题解答
为什么-march=corei7/-march=corei7-avx无法生成FMA指令?
- GCC的
-march=corei7对应Nehalem架构的Core i7,-march=corei7-avx对应Sandy Bridge/Ivy Bridge架构,这两代CPU本身不支持FMA(融合乘加)指令集——FMA是Intel Haswell架构(第四代Core i7)才正式引入的硬件指令。编译器不会为不支持该指令的目标架构生成FMA代码,和优化选项无关。
为什么-mfma或-march=haswell能生效?
-march=haswell会告诉编译器目标CPU是Haswell架构,该架构原生支持FMA,同时会启用对应优化规则,允许生成FMA指令。-mfma是手动强制启用FMA指令集支持,只要编译器确认硬件兼容,就会生成FMA代码(需配合-O3开启优化,以及-ffast-math允许编译器用FMA替换a*b+c——因为FMA的计算精度和分开的乘加略有差异,严格浮点模式下编译器不会自动替换)。
关于MinGW栈对齐Bug的疑问
早期MinGW确实存在AVX指令的栈对齐问题,但和你的情况无关:
- 指定
-march=haswell时,编译器会自动处理Haswell架构要求的栈对齐规则,规避了旧的对齐bug; - 而
-march=corei7/corei7-avx本身不支持FMA,根本不会涉及FMA的栈对齐问题——你之前的无效尝试本质是目标架构不支持FMA,而非栈对齐bug导致禁用。
补充测试验证
如果你的CPU是Haswell及以后型号,用以下编译命令可生成FMA指令:
gcc -O3 -ffast-math -mfma test.c -S
查看汇编会得到vfmadd213ss %xmm2, %xmm1, %xmm0这类FMA指令。
内容的提问来源于stack exchange,提问作者BadHellie
相关产品推荐
相关产品推荐

