为什么`gcc -Q -march = corei7-avx -help = target`在哪?

时间:2014-12-10 23:31:49

标签: c gcc

如果我们查询-march=native展开的内容,结果似乎应该是

$ gcc -Q -march=native --help=target | grep -E '^\s+-.*(sse|march)'
  -march=                           corei7-avx
  -mno-sse4                         [disabled]
  -msse                             [enabled]
  -msse2                            [enabled]
  -msse2avx                         [disabled]
  -msse3                            [enabled]
  -msse4                            [enabled]
  -msse4.1                          [enabled]
  -msse4.2                          [enabled]
  -msse4a                           [disabled]
  -msse5                            
  -msseregparm                      [disabled]
  -mssse3                           [enabled]

但如果直接指定了体系结构,gcc会丢弃它为native启用的SSE标志,为什么?

 $ gcc -Q -march=corei7-avx --help=target | grep -E '^\s+-.*sse'
  -mno-sse4                         [enabled]
  -msse                             [disabled]
  -msse2                            [disabled]
  -msse2avx                         [disabled]
  -msse3                            [disabled]
  -msse4                            [disabled]
  -msse4.1                          [disabled]
  -msse4.2                          [disabled]
  -msse4a                           [disabled]
  -msse5                            
  -msseregparm                      [disabled]
  -mssse3                           [disabled]

然而,使用-march=corei7-avx进行编译表明,它们将被启用。

$ echo | gcc -march=corei7-avx -dM -E - | grep -i sse
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSE2__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE3__ 1

2 个答案:

答案 0 :(得分:3)

我猜了一下,但无论如何,这对评论来说太长了......

看一下这个命令的输出:

$ echo | gcc -march=native -v -x c -c -

另一个:

$ echo | gcc -march=corei7-avx -v -x c -c -

有趣的部分是对cc1二进制文件的调用。在-march=native情况下,它将被所有目标选项替换,而不仅仅是等效的-march选项。我有一个sandybridge,所以在我的机器上它给出了:

.../cc1 -march=sandybridge -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 \
        -mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mpclmul \
        -mpopcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop ...

当你在我的案例中添加-march=corei7-avx或(-march=sandybridge)时,没有那些特定的架构选项。

现在我的结论是:

-Q --help=target的输出判断是否设置了给定的编译器选项,而不是实际启用了功能。实际上,可以通过不同方式启用或禁用其中一些功能。

例如,可以使用-msse启用SSE,也可以使用-march=corei7-avx-march=sandybridge启用SSE。但是,虽然指定-march=corei7-avx启用了SSE,但它并未设置-msse选项本身

另一方面,-march=native设置了很多选项,不仅包括实际的-march,还包括可以从运行时系统获取的任何其他相关选项,例如缓存大小。

正如您已经注意到的那样,检查特定功能是打开还是关闭的正确方法是检查预定义的defines

答案 1 :(得分:3)

这是GCC (39851)中的已知错误;它自2009年GCC 4.5以来一直开放。