GCC 优化
本指南 介绍了使用安全,理智的 CFLAGS 和 CXXFLAGS 来优化编译代码。 它还概述了优化背后的理论。
Default CFLAGS can be set in make.conf for Gentoo systems. CFLAGS can also be specified per-package.
介绍
什么是 CFLAGS 和 CXXFLAGS?
什么是 CFLAGS 和 CXXFLAGS?
CFLAGS 和 CXXFLAGS 是在编译C与C++代码时通常用于指定编译系统的编译器选项的环境变量之一. 虽然这些变量没有标准化, 它们的使用基本上是普遍存在的,任何正确编写的构建都应该理解这些,以便在调用编译器时传递额外或自定义选项. 查阅 GNU make 信息页面,查看该类别中一些常用变量的列表。
因为大多数构成Gentoo系统的包都编写自C与C++语言, 这是管理员肯定希望正确设置的两个变量 因为他们将对系统的大部分构建方式产生极其大的影响
它们可以被用于减少程序调试信息的数量, 或提高错误警告级别, 当然, 也可以优化生成的代码.这个文档 GCC manual 维护了一个完整的可选项及其用途的列表
它们该如何使用?
通常, CFLAGS 和 CXXFLAGS 将会在调用配置脚本或者由 automake 生成的makefiles时被设置在环境变量中. 在基于Gentoo的系统中, CFLAGS 和 CXXFLAGS 变量被设置于 /etc/portage/make.conf. 该文件中设置的变量将会被导出至被Portage调用的程序中, 这样所有的包将会以这些选项为基础进行编译
CFLAGS="-march=skylake -O2 -pipe"
CXXFLAGS="${CFLAGS}"
虽然 USE 可能会有多行,但是在 CFLAGS 中有很多行将会在程序中导致错误例如 cmake. 请确保 CFLAGS 声明在一行上, 并且添加一些尽可能少的空格以避免问题. 查阅 bug #500034 示例.
如上例所示,CXXFLAGS变量设置为使用CFLAGS中存在的所有选项。几乎每个系统都应该以这种方式进行配置。CXXFLAGS的其他选项不太常见,通常应用得不够普遍,不值得全局设置。
Safe CFLAGS 这篇文章可能会帮助初学者开始优化他们的系统.
误区
虽然启用各种CFLAGS的编译器优化可以有效地生成更小和/或更快的二进制文件,但它们也可能损害代码的功能、扩大代码大小、减慢代码执行时间,或者导致构建失败。当处理CFLAGS时,性能回报递减的点会很快达到。所以请不要随意设置。
请记住, CFLAGS 全局变量设置于 /etc/portage/make.conf 将会被应用于系统上的每一个包 所以管理员通常只用设置为广泛适用的选项. 各个包在ebuild或构建系统本身中进一步修改这些选项,以生成调用编译器时使用的最后一组标志。
准备好了么?
意识到所涉及的风险后,看看一些合理安全的优化. 这些将起到很好的作用,并将在下次Bugzilla 上报告问题时受到开发人员的喜爱.(开发人员通常会要求用户重新编译具有最小CFLAGS的包,以查看问题是否仍然存在。记住:攻击性标志会破坏代码!)
优化
基础
CFLAGS和CXXFLAGS背后的目标是创建针对系统量身定制的代码;如果可能的话,它应该在保持苗条和快速的同时发挥完美的功能。有时,这些条件是相互排斥的,因此本指南将坚持使用已知效果良好的组合。理想情况下,它们是任何CPU体系结构中最好的。出于参考目的,稍后将介绍攻击性标志的使用。并不是GCC手册上列出的每一个选项(有数百个)都会被讨论,但会讨论最常见的基本标志。
-march
第一个也是最重要的选项是-march
。这告诉编译器应该为系统的processor architecture(或 arch)生成什么代码;它告诉GCC它应该为某种CPU生成代码。不同的CPU具有不同的功能,支持不同的指令集,并具有不同的代码执行方式。-march
标志将指示编译器为系统的CPU生成特定的代码,包括其所有功能、特性、指令集、quirks等,前提是源代码已准备好使用它们。例如,为了从AVX指令中获益,需要对源代码进行调整以支持它。
-march=
是一个ISA选择选项;它告诉编译器它可以使用来自ISA的指令。在-march=native-O2
或更低优化级别的Intel/AMD64平台上,代码最终可能会使用AVX指令,但使用更短的SSE XMM寄存器。为了充分利用AVX YMM寄存器,还应使用-ftree-vectorize
、-O3
或-Ofast
选项[1]。
-ftree-vectorize
是一个优化选项(默认值为-O3
和-Ofast
),如果可能,它会尝试使用所选ISA对循环进行矢量化。它以前没有在-O2
中启用的原因是它并不总是能改进代码,它也会使代码变慢,而且通常会使代码变得更大;它实际上取决于循环等。从GCC 12开始,它默认启用低成本模型(-fvect-cost-model=very-cheap
),以在代码大小和速度优势之间取得平衡。可以使用-fvect-cost-model
指定消耗模型。
即使/etc/portage/make.conf中的CHOST变量指定了所使用的通用体系结构,仍应使用-march
,以便可以针对特定于系统的处理器优化程序。x86和x86-64 CPU(以及其他CPU)应该使用-march
标志。
系统使用哪种 CPU?运行下面的命令查找:
user $
cat /proc/cpuinfo
或者安装app-portage/cpuid2cpuflags,并将可用的CPU特定选项添加到/etc/portage/package.use/00cpuflags 文件, 该工具通过例如CPU_FLAGS_*变量执行该操作:
user $
cpuid2cpuflags
CPU_FLAGS_X86: aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt sha sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3
root #
cpuid2cpuflags | sed 's/\([^=]*\): \([^=]*\)/\1="\2"/' >> /etc/portage/make.conf
要获得更多详细信息,包括march
和mtune
值,可以使用两个命令。
- 第一个命令告诉编译器不要进行任何链接(
-c
),而不是解释--help
选项来澄清命令行选项,它现在显示某些选项是启用还是禁用(-Q
。在这种情况下,显示的选项是为所选目标启用的选项:user $
gcc -c -Q -march=native --help=target
- 第二个命令将显示用于构建头文件的编译器指令,但不实际执行步骤,而是在屏幕上显示它们(
-###
)。最后一个输出行是包含所有优化选项和架构选择的命令:user $
gcc -### -march=native /usr/include/stdlib.h
- glibc hwcaps功能(>=sys-libs/gglibc-2.33)可用于为更通用的处理器体系结构(对于>=sys-devel/gcc-11)定义
-march
:
user $
/lib64/ld-linux-x86-64.so.2 --help
... Subdirectories of glibc-hwcaps directories, in priority order: x86-64-v4 x86-64-v3 (supported, searched) x86-64-v2 (supported, searched) x86_64 (supported, searched)
在本例中,cpu支持x86-64-v3 psABI x86_64,可用于-march=x86-64-v3
。
现在让我们看看-march
的实际操作。此示例适用于较旧的AMD Athlon 64芯片:
CFLAGS="-march=athlon64"
CXXFLAGS="${CFLAGS}"
这是另一个适用于普遍Intel处理器的示例
CFLAGS="-march=skylake"
CXXFLAGS="${CFLAGS}"
如果CPU的类型没有确定,或者用户并不知道如何设置,可以使用-march=native
来设置. 当此flag被使用, GCC将会尝试去调查CPU然后为它自动设置正确的flag. 但是,当打算为不同的CPU编译包时,不应使用此选项!!!!!
如果在一台计算机上编译程序包以便在另一台计算机中运行(例如,当使用快速计算机为较旧、较慢的计算机构建时),则“不要”使用-march=native
。“本机”意味着生成的代码将“仅”在该类型的CPU上运行。在英特尔酷睿CPU上使用-march=native
构建的应用程序将“无法”在旧的英特尔Atom CPU上运行。
还提供了-mtune
和-mcpu
标志。这些标志通常只在没有可用的-march
选项时使用;某些处理器体系结构可能需要-mtune
,甚至-mcpu
。不幸的是,GCC的行为与每个flag从一个架构到下一个架构的行为不太一致。
在x86和x86-64 CPU上,-march
将使用其可用的指令集和正确的ABI生成专门用于该CPU的代码;对于较旧的/不同的CPU,它将没有向后兼容性。在为i386和i486等旧CPU生成代码时,请考虑使用-mtune
-mtune
生成的泛型代码比-march
多;尽管它将为某个CPU调优代码,但它没有考虑可用的指令集和ABI。不要在x86或x86-64系统上使用-mcpu
,因为这些体系结构不赞成使用它。
只有非x86/x86-64 CPU(如ARM、SPARC、Alpha和PowerPC)可能需要-mtune
或-mcpu
,而不是-march
。在这些体系结构上,-mtune
/-mcpu
有时的行为与-march
(在x86/x86-64上)类似,但具有不同的标志名称。同样,GCC的行为和标志命名在不同的体系结构中是不一致的,所以一定要查阅GCCmanual,以确定应使用哪一个。
有关更多建议的
-march
/ -mtune
/ -mcpu
设置, 请阅读 Gentoo Installation Handbook 中关于架构的第五章. 也请查阅GCC帮助文档表 architecture-specific options, 以及关于 -march
, -mcpu
, and -mtune
之间更详细的差异.-O
使用
-O3
或 -Ofast
将会导致一些包在编译时损坏或运行时产生意料之外的行为.可以通过如下的命令来打印出所有指定了 CFLAGS/CXXFLAGS变量的包:
grep Ofast /var/db/pkg/*/*/CFLAGS
接下来是-O
变量。此变量控制优化的总体级别。更改此值将使代码编译花费更多时间,并将占用更多内存,尤其是在优化级别提高时。
有八个-O
设置:-O0
, -O1
, -O2
, -O3
, -Os
, -Oz
, -Og
, and -Ofast
。需要注意的是,只能在/etc/portage/make.conf中使用其中一个。
除了-O0
之外,-O
设置每个都会激活几个额外的flag,因此请务必阅读GCC手册中关于optimization options了解每个-O
级别分别会激活哪些标志,以及关于它们的作用的一些解释。
让我们查看一下每个优化级别:
-O0
:如果CFLAGS或CXXFLAGS中未指定-O
级别,则此级别(即字母“O”后跟零)完全关闭优化,并且是默认级别。这减少了编译时间,可以改善调试信息,但如果不启用优化,某些应用程序将无法正常工作。除非出于调试目的,否则不建议使用此选项。
-O1
:最基本的优化级别。编译器将尝试在不占用太多编译时间的情况下生成更快、更小的代码。这是基本的,但它应该一直完成工作。
-O2
:比-O1
更上一层楼。“推荐”级别的优化,除非系统有特殊需求.除了-O1
激活的标志外,-O2
还会激活更多标志。使用-O2
,编译器将尝试在不影响大小和不占用太多编译时间的情况下提高代码性能。SSE或AVX可以在该级别使用,但除非-ftree-vectorize
也被启用,否则不会使用YMM寄存器。
-O3
:启用-O2
以及在编译时间和内存使用方面代价高昂的优化。使用-O3
编译并不能保证提高性能,事实上,在许多情况下,由于较大的二进制文件和增加的内存使用量,可能会降低系统的速度-O3
也会破坏几个包。不建议使用-O3
。然而,它也启用-ftree-vectorize
,以便代码中的循环得到矢量化,并将使用AVX YMM寄存器。
-Ofast
:GCC 4.7中的新增功能,由-O3
加上-ffast-math
、-fno-protect-parens
,-fallow-store-data-races
以及-fstack-arrays
和-fno-semantic-interposition
组成。此选项违反了严格的标准遵从性,不建议使用。
-Os
:根据大小优化代码。它激活所有不增加生成代码大小的-O2
选项。它对于磁盘存储空间极其有限的机器和/或缓存大小较小的CPU非常有用。
-Oz
:在GCC 12.1中引入,比-Os
更积极地优化大小。请注意,与-O2
相比,这将严重降低运行时性能,因为如果这些指令需要更少的字节进行编码,则会增加执行的指令数量。
-Og
:在GCC 4.8中,引入了一个新的通用优化级别-Og
。它满足了对快速编译和卓越调试体验的需求,同时提供了合理的运行时性能水平。开发的总体经验应该优于默认的优化级别-O0
。请注意,-Og
并不意味着-g
,它只是禁用可能干扰调试的优化。
如前所述,-O2
是建议的优化级别。如果包编译失败,并且不使用-O2
,请尝试使用该选项进行重建。作为后备选项,请尝试将CFLAGS和CXXFLAGS设置为较低的优化级别,例如-O1
,甚至-O0 -g2 -ggdb
(用于错误报告和检查可能的问题)。
-pipe
一个常见的标志是-pipe
。此标志对生成的代码没有影响,但它使编译过程更“快”。它告诉编译器在编译的不同阶段使用管道而不是临时文件,这会占用更多的内存。在内存不足的系统上,GCC可能会被杀死。在这些情况下,请不要使用此标志。
-fomit-frame-pointer
这是一个非常常见的标志,旨在减少生成的代码大小。在-O
的所有级别(-O0
除外)及在这样做不会干扰调试的架构(如x86-64)上都会打开它,但可能需要激活它。在这种情况下,将其添加到标志中。尽管GCC手册没有指定所有架构,但它是通过使用-O
选项打开的。仍然需要显式启用-fomit-frame-pointer
选项,以便在具有GCC 4.6版本的x86-32上激活它,或者在具有GCC任何版本的x86-22上使用-Os
时激活它。但是,使用-fomit-frame-pointer
会使调试变得困难或不可能。
特别是,它使由Java编写并由gcj编译的应用程序更难进行故障排除,尽管Java并不是唯一受此标志影响的代码。因此,虽然标志可以提供帮助,但它也使调试更加困难;特别是回溯将毫无用处。当没有进行软件调试并且没有使用其他与CFLAGS相关的调试时,如-ggdb
,请尝试使用code>-fomit-frame-pointer.
不要 联用
-fomit-frame-pointer
和类似的flags -momit-leaf-frame-pointer
. 不鼓励使用后一个flag, 因为-fomit-frame-pointer
已经正确的完成了这些工作. 此外, -momit-leaf-frame-pointer
已被证明会对代码性能产生负面影响.-msse, -msse2, -msse3, -mmmx, -m3dnow
这些标志激活了 Streaming SIMD Extensions (SSE), SSE2, SSE3, MMX, 和 3DNow! x86与x86-64的指令集. 这些主要在多媒体、游戏和其他浮点密集型计算任务中有用,尽管它们也包含其他一些数学增强功能。这些指令集出现在更现代的CPU中。
请确保通过运行cat /proc/cpuinfo来查看CPU是否支持这些指令集 . 输出将包括任何支持的附加指令集。请注意 pni只是SSE3的不同名称.
通常,只要系统使用正确的-march
(例如,-march=nocona
意味着-msse3
),就不需要将这些标志添加到/etc/portage/make.conf中。一些值得注意的例外是较新的VIA和AMD64 CPU,它们支持-march
未包含的指令(如SSE3)。对于像这样的CPU,在检查/proc/cpuinfo后,需要在适当的地方启用这些附加标志。
查阅 list of x86 and x86-64-specific flags 以查看这些指令集中哪一个指令集被正确的CPU类型标志激活。如果列出了指令,则无需单独指定;它将通过使用正确的
-march
设置来打开。Hardening optimizations
虽然可以使用hardened profile,但肯定没有必要在不同的配置文件上向/etc/portage/make.conf添加一些Hardening标志。特别是在桌面系统上,在系统范围内使用位置无关代码(PIC)和位置无关可执行文件(PIE)可能会导致编译失败。
Hardening 一个unhardened的系统,比如使用profile时,也可以被视为GCC优化,特别是考虑到Meltdown和Spectre.
某些软件包具有单独的<code>[1]USE标志,启用经过测试的安全增强功能(如CFLAG/CXXFLAG)。在/etc/portage/make.conf中的系统范围设置它们内可能是个好主意。
请阅读 Do I need to pass any flags to LDFLAGS/CFLAGS in order to turn on hardened building? 中的Hardened/FAQ 被建议用于检索一些基本的hardened CFLAGS/CXFLAGSCFLAGS/CXXFLAGS.
修改 CFLAGS/CXXFLAGS 会导致一些问题,甚至某些情况下会导致系统无法使用. 使用emerge -e @world重新构建系统可能会解决这个问题.
溢出保护
如果安全问题大于速度优化,那么优化CFLAGS/CXFLAGS以实现溢出保护可能是个好主意。这可能是日常使用的桌面系统的情况.但是例如在优化的游戏PC上,这将被认为是适得其反的。
对于GCC版本12的程序包 sys-devel/GCC,USE flag default-stack-clash-protection
和default-znow
将自动启用额外的溢出保护。
许多这样的flags通过GCC工具链,在内部自动应用于hardened的配置文件下,有些甚至在常规配置文件下。请参阅Hardened/Toolchain.
CFLAGS/CXXFLAGS | LDFLAGS | function |
---|---|---|
-D_FORTIFY_SOURCE=2
|
run-time buffer overflow detection | |
-D_GLIBCXX_ASSERTIONS
|
run-time bounds checking for C++ strings and containers | |
-fstack-protector-strong
|
stack smashing protector | |
-fstack-clash-protection
|
increased reliability of stack overflow detection | |
-fcf-protection
|
control flow integrity protection | |
-Wl,-z,defs
|
detect and reject underlinking | |
-Wl,-z,now
|
disable lazy binding | |
-Wl,-z,relro
|
read-only segments after relocation |
|-D_FORTIFY_SOURCE=2
|
|run-time buffer overflow detection
|-
|-D_GLIBCXX_ASSERTIONS
|
|run-time bounds checking for C++ strings and containers
|-
|-fstack-protector-strong
|
|stack smashing protector
|-
|-fstack-clash-protection
|
|increased reliability of stack overflow detection
|-
|-fcf-protection
|
|control flow integrity protection
|-
|
|-Wl,-z,defs
|detect and reject underlinking
|-
|
|-Wl,-z,now
|disable lazy binding
|-
|
|-Wl,-z,relro
|read-only segments after relocation
|-
|}
ASLR
Address Space Layout Randomization (ASLR)是一种最先进的措施,通过在内存中随机放置每个函数和缓冲区来提高安全性。这使得攻击向量更难成功。
PIE is enabled by default when it is safe to do so on all 17.0 profiles[3]. PIC may also be enabled by default on executables for architectures that require it (like AMD64).
There is no need to set PIE or PIC manually in CFLAGS.
CFLAGS/CXXFLAGS | LDFLAGS | function |
---|---|---|
-fpie
|
-Wl,-pie
|
full ASLR for executables |
-fpic -shared
|
no text relocations for shared libraries |
|-fpie
|-Wl,-pie
|full ASLR for executables
|-
|-fpic -shared
|
|no text relocations for shared libraries
|-
|}
优化常见问题
GCC的更高版本应该意味着更好的优化吗?
Not always because of software regression, where an optimization with an earlier version of GCC no longer optimizes. A full list of regressions can be found at this link. Should this happen, please file a bug to Gentoo's bugzilla and/or GCC's bugzilla.
存在完美的优化吗?
很遗憾没有, 因为halting problem,在这里可以判断任何程序是否会永远运行与停止[4].
Translations:GCC optimization/155/zh-cn
那么优化GCC本身怎么样呢?
gcc 有 pgo
和 lto
use flags, 它们分别启用了Profile Guided Optimization和Link Time Optimization。要启用使用PGO和LTO构建gcc本身,请执行以下操作:
sys-devel/gcc pgo lto
在Gentoo中,完成了gcc的stage3引导,这意味着它自己编译了三次[5]。在阶段1中,使用旧的gcc来编译{{c|gcc}}。在stage2中,gcc是使用stage1{{c| gcc}}编译的。在stage3中,gcc使用stage2gcc编译,并用于验证stage2gcc和stage3 gcc是否相同。这样做是因为它经过了更全面的测试,性能更好。lto
使用标志将-flto添加到BOOT_CFLAGS。pgo
use标志将-fprofile generate
添加到第2阶段gcc,并将-fprofile-use -fprofile-reproducible=parallel-runs
添加到 stage4 gcc.
gcc 通过PGO可以提高性能,尽管它可能会使编译时间增加一倍。
但我得到了更好的性能通过-funroll-loops -fomg-optimize!
No, people only think they do because someone has convinced them that more flags are better. Aggressive flags will only hurt applications when used system-wide. Even the GCC manual says that using -funroll-loops
and -funroll-all-loops
will make code larger and run more slowly. Yet for some reason, these two flags, along with -ffast-math
, -fforce-mem
, -fforce-addr
, and similar flags, continue to be very popular among ricers who want the biggest bragging rights.
The truth of the matter is that they are dangerously aggressive flags. Take a good look around the Gentoo Forums and Bugzilla to see what those flags do: nothing good!
These flags are not needed globally in CFLAGS or CXXFLAGS. They will only hurt performance. They might bring on the idea of having a high-performance system running on the bleeding edge, but they don't do anything but bloat the code and get bugs marked INVALID or WONTFIX.
Dangerous flags like these are not needed. Don't use them. Stick to the basics: -march
, -O
, and -pipe
.
What about -O levels higher than 3?
Some users boast about even better performance obtained by using -O4
, -O9
, and so on, but the reality is that -O
levels higher than 3 have no effect. The compiler may accept CFLAGS like -O4
, but it actually doesn't do anything with them. It only performs the optimizations for -O3
, nothing more.
Need more proof? Examine the source code:
case OPT_LEVELS_3_PLUS:
enabled = (level >= 3);
break;
case OPT_LEVELS_3_PLUS_AND_SIZE:
enabled = (level >= 3 || size);
break;
As can be seen, any value higher than 3 is treated as just -O3
.
What about compiling outside the target machine?
Some readers might wonder if compiling outside the target machine with a strictly inferior CPU or GCC sub-architecture will result in inferior optimization results (compared to a native compilation). The answer is simple: No. Regardless of the actual hardware on which the compilation takes place and the CHOST for which GCC was built, as long as the same arguments are used (except for -march=native
) and the same version of GCC is used (although minor version might be different), the resulting optimizations are strictly the same.
To exemplify, if Gentoo is installed on a machine whose GCC's CHOST is i686-pc-linux-gnu, and a Distcc server is setup on another computer whose GCC's CHOST is i486-linux-gnu, then there is no need to be afraid that the results would be less optimal because of the strictly inferior sub-architecture of the remote compiler and/or hardware. The result would be as optimized as a native build, as long as the same options are passed to both compilers (and the -march
parameter doesn't get a native
argument). In this particular case the target architecture needs to be specified explicitly as explained in Distcc.
The only difference in behavior between two GCC versions built targeting different sub-architectures is the implicit default argument for the -march
parameter, which is derived from the GCC's CHOST when not explicitly provided in the command line.
What about redundant flags?
Oftentimes CFLAGS and CXXFLAGS that are turned on at various -O
levels are specified redundantly in /etc/portage/make.conf. Sometimes this is done out of ignorance, but it is also done to avoid flag filtering or flag replacing.
Flag filtering/replacing is done in many of the ebuilds in the Portage tree. It is usually done because packages fail to compile at certain -O
levels, or when the source code is too sensitive for any additional flags to be used. The ebuild will either filter out some or all CFLAGS and CXXFLAGS, or it may replace -O
with a different level.
The Gentoo Developer Manual outlines where and how flag filtering/replacing works.
It's possible to circumvent -O
filtering by redundantly listing the flags for a certain level, such as -O3
, by doing things like:
CFLAGS="-O3 -finline-functions -funswitch-loops"
However, this is not a smart thing to do. CFLAGS are filtered for a reason! When flags are filtered, it means that it is unsafe to build a package with those flags. Clearly, it is not safe to compile the whole system with -O3
if some of the flags turned on by that level will cause problems with certain packages. Therefore, don't try to "outsmart" the developers who maintain those packages. Trust the developers. Flag filtering and replacing is done to ensure stability of the system and application! If an ebuild specifies alternative flags, then don't try to get around it.
Building packages with unacceptable flags will most likely lead to problems. When reporting problems on Bugzilla, the flags that are used in /etc/portage/make.conf will be readily visible and developers will ask to recompile without those flags. Save the trouble of recompiling by not using redundant flags in the first place! Don't just automatically assume to be more knowledgeable than the developers.
LDFLAGS 怎么样?
The Gentoo developers have already set basic, safe LDFLAGS in the base profiles, so they do not need to be changed.
我能使用per-package flags吗?
Using per-package flags complicates debugging and support. Make sure to mention the use of this feature in the bug reports together with the changes made.
Information on how to use per-package environment variables (including CFLAGS) is described in the Gentoo Handbook, "Per-Package Environment Variables".
Profile Guided Optimization (PGO)
Profile guided optimization (PGO) consists of compiling and profiling a program to assess hot paths in the code. Optimizations are then applied based on this analysis. Specifically, the code is compiled with -fprofile-generate
, which instrument the code. Second, the code is run with applications to collect profile information. Finally, using the profiled data, the code is compiled with -fprofile-use
. To manually enable PGO for packages, see this link.
Firefox also supports PGO although sometimes it may break the build.
Link Time Optimization (LTO)
LTO heavily increases compile times and if changing even one object file when compiling, LTO recompiles the whole code again. There is a ongoing GSoC project to make sure LTO only recompiles what it deems necessary.
LTO is still experimental. LTO may need to be disabled before reporting bugs because it is a common source of problems. The -flto
flag is used, with an optional auto
argument (Detects how many jobs to use) or a integer argument (An integer number of jobs to execute parallel).
See the LTO article for more information on LTO on Gentoo.
另请参阅
- Configuring compile options (AMD64 Handbook)
- CPU_FLAGS_* — 包含指令集和其他 CPU 特定功能的 USE_EXPAND 变量。
- Safe CFLAGS — a summary of "safe" settings for CFLAGS on Gentoo Linux.
外部资源
以下资源有助于进一步了解优化:
参考
- ↑ GNU GCC BugzillaAVX/AVX2 no ymm registers used in a trivial reduction。检索日期:2017/07/18。
- ↑ GNU GCC Bugzilla, 'gcc -marc=native' sets L2 cache size equal to L3 cache size on i7 and i5 CPU. Retrieved on 2022/08/14.
- ↑ New 17.0 profiles in the Gentoo repository
- ↑ https://en.wikipedia.org/wiki/Full-employment_theorem
- ↑ https://gcc.gnu.org/install/build.html
This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document:
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.