如何查看将激活哪些标志-March=native?

我正在使用GCC 4.3编译我的C++应用程序。我没有手动选择优化标志,而是使用-march=native,理论上它应该添加适用于正在编译的硬件的所有优化标志。但是我如何检查它实际使用的是哪些标志呢?

117546 次浏览

您可以使用-Q --help=target选项:

gcc -march=native -Q --help=target ...

也可以使用-v选项。

您可以查看有关--help选项在这里的文档。

要查看命令行标志,请使用:

gcc -march=native -E -v - </dev/null 2>&1 | grep cc1

如果要查看由某些参数设置的编译器/预编译器定义,请执行以下操作:

echo | gcc -dM -E - -march=native

它应该是(-###类似于-v):

echo | gcc -### -E - -march=native

显示GCC的“真正”本地标志。

您可以使用以下命令使它们看起来更“清晰”:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )//g'

你可以用-MnO-*去掉标志:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )|( -mno-[^\ ]+)//g'

如果您想了解如何设置非本机交叉编译,我发现这很有用:

在目标计算机上,

% gcc -march=native -Q --help=target | grep march
-march=                               core-avx-i

然后在构建机器上使用这个:

% gcc -march=core-avx-i ...

我将在这个问题上发表我的意见,并建议对伊莱亚斯的回答进行稍微详细的扩展。从GCC 4.6开始,运行gcc -march=native -v -E - < /dev/null会以多余的-mno-*标志的形式发出越来越多的垃圾邮件。以下内容将去除这些:

gcc -march=native -v -E - < /dev/null 2>&1 | grep cc1 | perl -pe 's/ -mno-\S+//g; s/^.* - //g;'

但是,我只在两个不同的CPU(Intel Core2和AMD Phenom)上验证了这一点的正确性,因此我建议同时运行以下脚本,以确保可以安全地剥离所有这些-mno-*标志。

2021年编辑:确实存在这样的机器,其中-march=native使用特定的-march值,但是必须使用-mno-*禁用某些隐含的ISA(指令集体系结构)。

#!/bin/bash


gcc_cmd="gcc"


# Optionally supply path to gcc as first argument
if (($#)); then
gcc_cmd="$1"
fi


with_mno=$(
"${gcc_cmd}" -march=native -mtune=native -v -E - < /dev/null 2>&1 |
grep cc1 |
perl -pe 's/^.* - //g;'
)
without_mno=$(echo "${with_mno}" | perl -pe 's/ -mno-\S+//g;')


"${gcc_cmd}" ${with_mno}    -dM -E - < /dev/null > /tmp/gcctest.a.$$
"${gcc_cmd}" ${without_mno} -dM -E - < /dev/null > /tmp/gcctest.b.$$


if diff -u /tmp/gcctest.{a,b}.$$; then
echo "Safe to strip -mno-* options."
else
echo
echo "WARNING! Some -mno-* options are needed!"
exit 1
fi


rm /tmp/gcctest.{a,b}.$$

我还没有发现gcc -march=native -v -E - < /dev/nullgcc -march=native -### -E - < /dev/null之间的区别,除了一些被引用的参数--以及不包含特殊字符的参数,所以我不确定在什么情况下这会产生任何真正的区别。

最后,请注意,--march=native是在GCC 4.2中引入的,在此之前,它只是一个无法识别的参数。