2011-03-29 105 views
126

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

回答

119

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

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

-v选项也可以使用。

您可以在--help选件here上看到相关文档。

+8

我想说这是次优。 --help = target的输出不显示CPU缓存信息,其中列出了elias和42n4中的方法。具体来说,在Phenom上的gcc 4.9.2上,输出包括:''--param l1-cache-size = 64 --param l1-cache-line-size = 64 --param l2-cache-size = 512 '' – 2015-01-29 00:22:10

+0

@DanielSantos:在我的系统中,它确实显示那些带有'-v'选项的参数,尽管它是'cc1'命令行的一部分... – thkala 2015-01-30 10:20:45

+0

不完美。在gcc版本5.4.0上(Buildroot 2017.05-rc2-00016-gc7eaf50-dirty)它会导致错误返回:汇编器消息: 错误:未知体系结构本机 错误:无法识别的选项-march = native。 因此,请松开'-march = native',它会在任何地方使用:'gcc -Q --help = target'。 – 2017-06-06 14:00:48

61

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

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

如果你想看到的编译器/预编译器定义了某些参数进行设置,这样做:

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

这个答案应该与接受的答案一样多,特别是列举“native”真正等同的东西。 – 2017-02-04 18:02:45

+0

所以如果我想跨跨本地编译,我应该同时提供定义和参数的编译器?或者是充分的论据? – hanshenrik 2017-12-21 02:18:22

14

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

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

为了显示“rea l“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' 
8

如果你想找到如何建立一个非原生交叉编译,我发现这个有用:

在目标机器上,

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

然后构建机器上使用此:

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

这不包括所有的标志不幸的。 – 2014-10-16 07:41:56

+0

@BaptisteWicht是否有标志,-march =本地将包括该-march =核心 - avx我不会,在这种情况下,或哪些标志?谢谢! – rogerdpack 2016-06-28 20:08:51

+2

@rogerdpack在这台计算机(sandybridge)上,march = sandybridge在march = native时不启用AVX(不知道为什么)。另一个重要的区别是缓存大小只能用march = native来提取 – 2016-06-29 07:03:49

7

我要我的两分钱投入到这个问题,并建议埃利亚斯的回答稍微更详细的扩展。从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(英特尔酷睿2及AMD羿龙),所以我建议还运行下面的脚本,以确保所有的这些-mno-*标志可以安全地被剥离。

#!/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中引入的,在此之前它只是一个无法识别的参数。

+0

不错,这个微笑也有缓存大小 – rogerdpack 2016-07-13 23:51:49

+0

gcc版本5.4.0(Buildroot 2017.05-rc2-00016-gc7eaf50-脏) 返回:错误:未知架构'本地' – 2017-06-06 13:35:13

+0

奥列格:你使用什么拱门?可能是“本机”仅在某些架构上受支持。 – 2017-06-07 14:19:18