如果我们查询-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
答案 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以来一直开放。