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

var*_*tec 152 gcc g++ compiler-flags compiler-optimization

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

thk*_*ala 138

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

gcc -march=native -Q --help=target ...
Run Code Online (Sandbox Code Playgroud)

-v选项也可能有用.

您可以在此处查看有关该--help选项的文档.

  • 我会建议这不是最理想的.--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 `` (10认同)

小智 99

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

gcc -march=native -E -v - </dev/null 2>&1 | grep cc1
Run Code Online (Sandbox Code Playgroud)

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

echo | gcc -dM -E - -march=native
Run Code Online (Sandbox Code Playgroud)

  • 因此,如果我想交叉原生编译,我应该同时向两个编译器提供定义和参数?还是论点足够? (3认同)
  • 这个答案值得与公认的一样多的赞成票,特别是列出了“原生”真正等同于什么。 (2认同)

42n*_*2n4 22

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

echo | gcc -### -E - -march=native 
Run Code Online (Sandbox Code Playgroud)

显示gcc的"真实"原生标志.

您可以使用命令使它们显得更"清晰":

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

你可以用-mno-*摆脱旗帜:

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


Mar*_*ata 10

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

在目标机器上,

% gcc -march=native -Q --help=target | grep march
-march=                               core-avx-i
Run Code Online (Sandbox Code Playgroud)

然后在构建机器上使用它:

% gcc -march=core-avx-i ...
Run Code Online (Sandbox Code Playgroud)

  • @rogerdpack在这台计算机(sandybridge)上,march = sandybridge不启用AVX(不知道为什么),而march = native.另一个重要区别是缓存大小仅使用march = native提取 (2认同)
  • @BaptisteWicht 这似乎很奇怪在这里起作用(我猜):`echo | gcc-6 -dM -E - -march=sandybridge | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1` 但缓存大小似乎不存在。 (2认同)

Dan*_*tos 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;'
Run Code Online (Sandbox Code Playgroud)

但是,我只在两个不同的CPU(Intel Core2和AMD Phenom)上验证了这一点的正确性,因此我建议运行以下脚本以确保-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}.$$
Run Code Online (Sandbox Code Playgroud)

我还没有找到之间的差异gcc -march=native -v -E - < /dev/nullgcc -march=native -### -E - < /dev/null其他比一些参数被引用-并且不包含特殊字符的参数,所以我不是在什么情况下,这使得任何真正的区别肯定.

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