Ste*_*mer 8 gcc cpu-architecture compiler-optimization
为了比较各种-march设置将启用哪些标志,我正在比较以下命令的输出,如本 SO 答案中所述:
$ gcc -Q -march=native --help=target
$ gcc -Q -march=skylake-avx512 --help=target
Run Code Online (Sandbox Code Playgroud)
请注意,为避免产生疑问,使用检测到的-march=native拱门输出为skylake-avx512。
$ gcc -Q -march=native --help=target | grep march
-march= skylake-avx512
Run Code Online (Sandbox Code Playgroud)
两个变体输出的大多数标志-march完全匹配。
但是,存在一些差异:
$ diff <(gcc -Q -march=native --help=target) <(gcc -Q -march=skylake-avx512 --help=target)
12c12
< -mabm [enabled]
> -mabm [disabled]
119c119
< -mpku [disabled]
> -mpku [enabled]
136c136
< -mrtm [enabled]
> -mrtm [disabled]
138c138
< -msgx [disabled]
> -msgx [enabled]
Run Code Online (Sandbox Code Playgroud)
正是这些差异促使我提出这个问题。
如何-march=native选择启用和禁用哪些指令集?
我有如下猜想:
-march=native将使用 CPUID 指令来计算支持的指令集等,以便检测处理器变体-march=foobar将使用处理器支持的指令集的硬编码列表foobar。如果这是正确的,那么我可以看到两种可能的解决方式:
选项1:
可能-march=native无法 100% 正确,而当发布新处理器时,支持的指令集表会更新,并且更有可能是正确的。
因此我们期望-march=foobar成为“更正确”的标志。
选项2:
-march=native将使用 CPUID 指令来计算支持的指令集 - 因此保证是正确的,而-march=foobar将使用可能不正确的硬编码指令集列表。
因此我们期望-march=native成为“更正确”的标志。
如果选项 2正确,人们可以推测 using-march=foobar可能最终会启用不受支持的指令集 - 并且如果程序发出这些指令会导致崩溃。
到目前为止,我还没有成功地找到上述任何一个或任何一个是否正确的答案。
如果我想针对特定架构,请确保启用所有(且仅)受支持的指令集,并且无法使用-march=native,那么最好的方法是什么?