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

Posted

技术标签:

【中文标题】如何查看哪些标志 -march=native 将激活?【英文标题】:How to see which flags -march=native will activate? 【发布时间】:2011-07-25 02:58:39 【问题描述】:

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

【问题讨论】:

【参考方案1】:

我将在这个问题上投入两分钱,并建议对 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 - &lt; /dev/nullgcc -march=native -### -E - &lt; /dev/null 之间的区别,除了一些被引用的参数——以及不包含特殊字符的参数,所以我不确定在什么情况下这有什么真正的区别。

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

【讨论】:

很好,这个收集器也有缓存大小 gcc 版本 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) 返回:错误:未知架构`native' Oleg:你用的是什么拱门?可能只有某些架构支持“本机”。【参考方案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'

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

这个答案应该得到与被接受的答案一样多的赞成票,特别是列出native真正等同于什么。 所以如果我想跨原生编译,我应该同时为编译器提供定义和参数?或者论据是否足够?【参考方案4】:

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

在目标机器上,

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

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

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

【讨论】:

不幸的是,这不会包括所有的标志。 @BaptisteWicht 是否存在 -march=native 将包含 -march=core-avx-i 在这种情况下不会包含的标志,或者哪些标志?谢谢! @rogerdpack 在这台计算机 (sandybridge) 上,march=sandybridge 不启用 AVX(不知道为什么),而 march=native 可以。另一个重要的区别是缓存大小仅使用 March=native 提取 @BaptisteWicht 这很奇怪似乎在这里工作(我猜):echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1 但缓存大小似乎不存在。【参考方案5】:

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

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

-v 选项也可能有用。

您可以在--help 选项here 上查看文档。

【讨论】:

我建议这是次优的。 --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 @DanielSantos:在我的系统上,它确实使用-v 选项显示这些参数,尽管它是cc1 命令行的一部分... 并不完美。在 gcc 版本 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-dirty) 上,它将导致错误返回:汇编程序消息:错误:未知架构本机错误:无法识别的选项 -march=native。所以,松开-march=native,它就可以在任何地方工作了:gcc -Q --help=target @Oleg - 这听起来像是 GCC 5 中的一个错误。这个问题在 GCC 7 中不存在。

以上是关于如何查看哪些标志 -march=native 将激活?的主要内容,如果未能解决你的问题,请参考以下文章

react native开发的应用都有哪些更新应用解决方案?

默认使用 React Native 打开 iOS iPad 模拟器

如何在 React Native 中查看网络请求(用于调试)?

我应该为我的库和应用程序使用哪些编译器标志以获得最佳性能 NDK (CMake)

我怎样才能知道 GCC 可以使用哪些标志来更轻松地链接库?

如何查看管理npm模块--react-native为例