-march 与 -mtune 有何不同?

问题描述 投票:0回答:2

我尝试为此擦洗 GCC 手册页,但仍然不明白,真的。

-march
-mtune
有什么区别?

什么时候一个人只使用

-march
,什么时候两者都使用?有可能只是
-mtune
吗?

gcc optimization flags
2个回答
128
投票

如果您使用

-march
,那么 GCC 将可以自由生成在指定 CPU 上运行的指令,但(通常)不能在架构系列中的早期 CPU 上运行。

如果您只使用

-mtune
,那么编译器将生成适用于其中任何一个的代码,但会优先考虑在您指定的特定 CPU 上运行最快的指令序列。 例如为该 CPU 适当设置循环展开启发式。


-march=foo
意味着
-mtune=foo
,除非您还指定了不同的
-mtune
。 这就是为什么使用
-march
比仅启用
-mavx
等选项而不做任何调整更好的原因之一。

警告:在 GCC 未明确识别的 CPU 上,

-march=native
仍将启用 GCC 可以检测到的新指令集,但会保留
-mtune=generic
。 如果您希望它编写出好的代码,请使用一个足够新的、了解您的 CPU 的 GCC。


60
投票

这是我用谷歌搜索到的:

-march=X
选项采用CPU名称
X
,并允许GCC生成使用
X
所有功能的代码。 GCC 手册准确解释了哪些 CPU 名称意味着哪些 CPU 系列和功能。

因为功能通常会添加,但不会删除,所以使用

-march=X
构建的二进制文件将在 CPU
X
上运行,很有可能在比
X
新的 CPU 上运行,但几乎可以肯定不会在任何较旧的 CPU 上运行比
X
。某些指令集(3DNow!,我猜?)可能特定于特定的 CPU 供应商,利用这些指令集可能会为您提供无法在竞争的 CPU(更新或其他)上运行的二进制文件。

-mtune=Y
选项可调整生成的代码,使其在
Y
上运行得比在其他 CPU 上运行得更快。
-march=X
意味着
-mtune=X
-mtune=Y
不会覆盖
-march=X
,因此,例如,它可能对
-march=core2
-mtune=i686
没有任何意义 - 你的代码无论如何都不会在任何早于
core2
的东西上运行,因为
-march=core2
,所以你究竟为什么要针对比 core2 更旧(功能较少)的东西进行优化?
-march=core2 -mtune=haswell
更有意义:不要使用超出
core2
提供的任何功能(这仍然比
-march=i686
为您提供的功能多得多!),但要针对较新的
haswell
CPU 优化代码,而不是针对
core2

还有

-mtune=generic
generic
使 GCC 生成在当前 CPU 上运行最佳的代码(
generic
的含义从一个版本的 GCC 更改为另一个版本)。 Gentoo 论坛上有传言称,
-march=X -mtune=generic
生成的代码在
X
上运行的速度比
-march=X -mtune=X
生成的代码运行得更快(或者只是
-march=X
,如
-mtune=X
所暗示的那样)。 不知道这是否属实。

一般来说,除非你确切地知道你需要什么,否则最好的做法似乎是指定

-march=<oldest CPU you want to run on>
-mtune=generic
-mtune=generic
在这里是为了对抗隐式的
-mtune=<oldest CPU you want to run on>
,因为你可能不想优化对于最旧的 CPU)。或者只是
-march=native
,如果您只想在构建的同一台机器上运行。

© www.soinside.com 2019 - 2024. All rights reserved.