同时使用-O3与-march=native编译mt19937代码触发汇编错误原因咨询
GCC编译报错原因分析
问题场景
有如下C++文件test.cc:
#include <iostream> #include <random> int main() { std::mt19937 rng(347 * 6007); std::cout << rng() << std::endl; return 0; }
执行编译命令:
g++ ./test.cc -o test -O3 -march=native
编译失败,报错信息如下:
[csc@fedora examples]$ g++ ./test.cc -o test -O3 -march=native /tmp/ccvnwhuu.s: Assembler messages: /tmp/ccvnwhuu.s:38: Error: selected processor does not support `eor3 v0.16b,v1.16b,v3.16b,v0.16b' /tmp/ccvnwhuu.s:73: Error: selected processor does not support `eor3 v0.16b,v1.16b,v6.16b,v0.16b'
但单独使用以下两个命令编译均可成功:
g++ ./test.cc -o test -O3g++ ./test.cc -o test -march=native
运行环境:搭载Apple M1芯片(ARM架构)的Linux Fedora 6.5.10-200.fc38.aarch64虚拟机,GCC版本为g++ (GCC) 13.2.1 20231011 (Red Hat 13.2.1-4)
原因分析
当同时启用-O3和-march=native时,GCC会在最高优化等级下,尝试生成利用目标处理器(Apple M1)支持的高级ARM指令集特性的代码。报错中的eor3指令属于ARMv8.5-A的NEON扩展指令,是M1硬件支持的特性。
但由于你运行的是M1上的Fedora虚拟机,虚拟机可能没有将M1的完整指令集特性完全暴露给Guest系统。此时GCC通过-march=native检测到的处理器特性与汇编器实际能识别的指令集不匹配:GCC生成了包含eor3的汇编代码,但汇编器认为当前处理器不支持该指令,最终导致编译失败。
单独使用-O3时,GCC默认采用通用的ARMv8-A指令集编译,不会生成这类高级指令;单独使用-march=native时,优化等级未达到-O3,GCC不会触发需要使用eor3指令的优化逻辑,因此编译可以正常完成。
内容的提问来源于stack exchange,提问作者陈思超
相关产品推荐
相关产品推荐

