我试图查阅GCC手册,但仍然不太明白。
-march
和-mtune
有什么区别?
在什么情况下只使用-march
,而在什么情况下需要同时使用两者?是否有可能只使用-mtune
?
我试图查阅GCC手册,但仍然不太明白。
-march
和-mtune
有什么区别?
在什么情况下只使用-march
,而在什么情况下需要同时使用两者?是否有可能只使用-mtune
?
-march
,那么GCC将生成适用于指定CPU的指令,但通常不适用于体系结构系列中较早的CPU。-mtune
,那么编译器将生成适用于其中任何一个的代码,但会优先考虑在您指定的特定CPU上运行最快的指令序列。例如,为该CPU适当设置循环展开启发式。
-march=foo
意味着-mtune=foo
,除非您还指定了不同的-mtune
。这是使用-march
比仅启用-mavx
等选项更好的原因之一,而不采取调整措施。-march=native
仍将启用GCC可以检测到的新指令集,但会保留-mtune=generic
。如果您希望它生成良好的代码,请使用足够新的GCC来了解您的CPU。-march=X
选项接受一个CPU名称X
,允许GCC生成使用X
所有特性的代码。GCC手册详细解释了哪些CPU名称意味着哪些CPU系列和特性。-march=X
构建的二进制文件将在CPU X
上运行,并有很大的机会在比X
更新的CPU上运行,但几乎肯定不会在任何旧于X
的CPU上运行。某些指令集(如3DNow!)可能特定于特定的CPU供应商,使用这些指令集可能会得到不能运行在竞争对手的CPU上的二进制文件,无论是更新的还是其他的。
-mtune=Y
选项调整生成的代码,使其在可能运行的其他CPU上比在Y
上更快。 -march=X
意味着-mtune=X
。 -mtune=Y
不会覆盖-march=X
,因此,例如,-march=core2
和-mtune=i686
可能没有意义——由于-march=core2
,您的代码将无法在任何旧于core2
的CPU上运行,因此为什么要优化比core2
还老的东西呢?-march=core2 -mtune=haswell
更有意义:不要使用超出core2
提供范围(这仍然比-march=i686
提供的要多得多!)的特性,但确实针对更新的haswell
CPU进行代码优化,而不是针对core2
。还有一个选项是-mtune=generic
。generic
让GCC生成在当前CPU上运行最佳的代码(generic
的含义随着GCC版本的变化而改变)。在Gentoo论坛上有传言说-march=X -mtune=generic
生成的代码比-march=X -mtune=X
(或仅-march=X
,因为-mtune=X
被隐含)生成的代码在X
上运行得更快。不知道这是否正确。
一般来说,除非您确切地知道您需要什么,否则最好的做法似乎是指定-march=<您要运行的最旧CPU>
和-mtune=generic
(-mtune=generic
在这里用于对抗隐含的-mtune=<您要运行的最旧CPU>
,因为您可能不想针对最旧的CPU进行优化)。或者如果您只打算在构建时运行在同一台机器上,可以使用-march=native
。
-march=native
,您可能想要指定-mtune=X
,因为默认值仍然是-mtune=generic
,如此处所述:https://lemire.me/blog/2018/07/25/it-is-more-complicated-than-i-thought-mtune-march-in-gcc/。 - Roland Webertune=generic
更好的支持,尤其是像 Kaby Lake 这样在微架构上与 Skylake 完全相同的处理器。但我认为它仍然有不同的系列/步进,因此只知道 Skylake 及更早版本的 GCC 可能无法识别并进行优化。 - Peter Cordes-march=native
也包含了-mtune=native
。通常情况下,厂商会让新的CPU能够高效地运行为早期一代所调整的机器码,至少不会有明显的减速。有时候可能会发现性能有所提升,例如在不同的展开次数之间选择最佳的方案,或者使用不同的指令等。Pentium 4曾试图避免这种情况,希望每个人都会重新编译以避免如inc
这样在P4上不够优化的指令,但结果并不是很好(主要原因还有其他),后来的CPU大多数情况下都没有这种缺陷。Silvermont仍然有些…… - Peter Cordes
mtune
和march
组合。这篇博客文章通过其他内容阐明了这一点:https://lemire.me/blog/2018/07/25/it-is-more-complicated-than-i-thought-mtune-march-in-gcc/ - qneill