【发布时间】:2011-07-25 02:58:39
【问题描述】:
我正在使用 GCC 4.3 编译我的 C++ 应用程序。我没有手动选择优化标志,而是使用-march=native,理论上应该添加适用于我正在编译的硬件的所有优化标志。但是如何检查它实际使用了哪些标志?
【问题讨论】:
标签: gcc g++ compiler-optimization compiler-flags
我正在使用 GCC 4.3 编译我的 C++ 应用程序。我没有手动选择优化标志,而是使用-march=native,理论上应该添加适用于我正在编译的硬件的所有优化标志。但是如何检查它实际使用了哪些标志?
【问题讨论】:
标签: gcc g++ compiler-optimization compiler-flags
我将在这个问题上投入两分钱,并建议对 elias 的答案进行更详细的扩展。从 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 值,但必须使用@987654327 禁用一些隐含的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/null 和gcc -march=native -### -E - < /dev/null 之间的区别,除了一些被引用的参数——以及不包含特殊字符的参数,所以我不确定在什么情况下这有什么真正的区别。
最后,请注意--march=native 是在 gcc 4.2 中引入的,在此之前它只是一个无法识别的参数。
【讨论】:
应该是(-###类似于-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 -E -v - </dev/null 2>&1 | grep cc1
如果您想查看由某些参数设置的编译器/预编译器定义,请执行以下操作:
echo | gcc -dM -E - -march=native
【讨论】:
native真正等同于什么。
如果您想了解如何设置非本地交叉编译,我发现这很有用:
在目标机器上,
% gcc -march=native -Q --help=target | grep march
-march= core-avx-i
然后在构建机器上使用这个:
% gcc -march=core-avx-i ...
【讨论】:
echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1 但缓存大小似乎不存在。
您可以使用-Q --help=target 选项:
gcc -march=native -Q --help=target ...
-v 选项也可能有用。
您可以在--help 选项here 上查看文档。
【讨论】:
--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
-v 选项显示这些参数,尽管它是cc1 命令行的一部分...
-march=native,它就可以在任何地方工作了:gcc -Q --help=target。