如何确定gcc支持哪些架构?

10
GCC支持一个-march开关,可以让您指定您的目标架构——从而调整该平台的指令序列,并使用可能在该平台上可用但不在“默认”或基本版本的架构上不可用的指令。例如,-march=skylake将告诉编译器以Skylake CPU为目标,包括使用在Skylake上可用的指令集,如AVX2。
如何确定本地版本的gcc支持哪些-march值?较新版本会在传递无效参数时有所帮助地列出有效参数,但较旧版本则没有。
4个回答

12

从gcc7版本开始,gcc将在错误消息中打印其支持的值。

$ gcc -E -march=help -xc /dev/null
# 1 "/dev/null"
cc1: error: bad value (‘help’) for ‘-march=’ switch
cc1: note: valid arguments to ‘-march=’ switch are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 bonnell atom silvermont slm knl x86-64 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 btver1 btver2

我在


在我的本地版本(5.4.1)中没有这个问题,我只是得到了“错误:-march=开关的坏值(help)”。不幸的是,旧版本正是我需要的地方。当我在7.2版本上尝试时,它确实起作用。 - BeeOnRope
@BeeOnRope:是的,太糟糕了。顺便说一下,这是特定于目标的。ARM gcc6.x确实为-mcpu=-march=生成有用的帮助信息。 - Peter Cordes

3
对于gcc-7.2.0,它在这里: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/x86-Options.html#x86-Options 您可以访问gcc在线文档。然后,找到您感兴趣的版本的手册。接着,转到机器相关选项部分。如果您正在查看x86,请跳转到“x86选项”部分。现在,搜索“-march”。
我还没有检查旧的gcc版本。另一种尝试的方法是检查源代码,并打开保留支持的架构的文字字符串的源代码。
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc_trunk
cd gcc_trunk

然后,也许你可以尝试像这样:

find . -type f | egrep "*\.(c|cc|cpp|h|hpp)$" | xargs egrep '"skylake-avx'

截至今天,在x86架构中,字面字符串存储在./gcc/config/i386/i386.c中。
%附言。
正如Peter所提到的,它似乎是机器特定的。我怀疑没有一个标准/期望的行为来列出可用的march值。例如,如果gcc刚刚移植到一个全新的指令集架构LEG(而不是ARM),它并不一定有一个命令行选项来列出所有支持的march值。
幸运的是,一些较新的gcc版本似乎提供了这样的方法。如果您确实需要旧版gcc的此选项,则可以考虑编写一个gcc插件,该插件可能从gcc 4.5左右开始工作: gcc plugin simple gcc plugin how to Gcc插件通过添加一些命令行选项来插入现有的gcc。 Gcc具有插件API。您所需要做的就是编写一个检查信息(如gcc版本,运行gcc的架构等)并打印出支持的march列表的代码。

谢谢。我希望有一种方法可以在命令行上调用gcc,或者其他我可以脚本化/自动化的东西。 - BeeOnRope
@Bee 想要查询已安装的 gcc,而不是在配置脚本中通过版本构建支持的 -march 参数表。 - Peter Cordes

1

使用详细的帮助页面:

gcc -v --help

寻找选项-march=CPU,例如在gcc v4.8.4中

  -march=CPU[,+EXTENSION...]
                          generate code for CPU and EXTENSION, CPU is one of:
                           generic32, generic64, i386, i486, i586, i686,
                           pentium, pentiumpro, pentiumii, pentiumiii, pentium4,
                           prescott, nocona, core, core2, corei7, l1om, k1om,
                           k6, k6_2, athlon, opteron, k8, amdfam10, bdver1,
                           bdver2, bdver3, btver1, btver2
                          EXTENSION is combination of:
                           8087, 287, 387, no87, mmx, nommx, sse, sse2, sse3,
                           ssse3, sse4.1, sse4.2, sse4, nosse, avx, avx2,
                           avx512f, avx512cd, avx512er, avx512pf, noavx, vmx,
                           vmfunc, smx, xsave, xsaveopt, aes, pclmul, fsgsbase,
                           rdrnd, f16c, bmi2, fma, fma4, xop, lwp, movbe, cx16,
                           ept, lzcnt, hle, rtm, invpcid, clflush, nop, syscall,
                           rdtscp, 3dnow, 3dnowa, padlock, svme, sse4a, abm,
                           bmi, tbm, adx, rdseed, prfchw, smap, mpx, sha,
                           clflushopt, xsavec, xsaves, prefetchwt1

1
自GCC 4以来,有一个--target-help选项,它会打印支持的参数列表,包括:
  • -march
  • -mtune
  • -mabi
  • -masm
  • 其他一些与架构相关的选项,例如-msse2-mavx2
注意:请保留原文中的HTML标签,谢谢!

1
输出结果相当冗长,但是我们需要的所有信息都在其中。还有其他特定目标选项存在。对于x86目标,这相当多,对于GCC(例如-maccumulate-outgoing-args)和GAS(例如Skylake JCC错误处理-mbranches-within-32B-boundaries,或者-mfence-as-lock-add=[no|yes]来优化mfence,或者-momit-lock-prefix=[no|yes]来优化单处理器或单线程代码的原子操作)。 - Peter Cordes
甚至有一个-muse-unaligned-vector-move选项,它可以与启用AVX一起使用,使得假定对齐内存的代码也能够处理未对齐内存。 - Peter Cordes
@Peter 是的,它很冗长。我将其管道传输到 less 并在那里搜索内容。我知道你的答案更好,但认为记录这个选项更好。 - legends2k
1
这是一个非常好的答案,尤其是如果它可以在所有架构上移植。它适用于旧版本的GCC。冗长只是一个小缺点,但对于其他一些原因来说是一个很大的优势。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接