主机调优GCC以加快编译速度

Lobsters Hottest 工具

摘要

这篇博客文章介绍了如何使用配置文件引导优化、LTO和-O3构建主机调优的GCC编译器,以实现更快的编译速度,并附有详细的说明和基准测试。

<p><a href="https://lobste.rs/s/c7dq7x/host_tuned_gcc_for_faster_compilation">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/05/25 13:08

# 构建一个面向宿主优化的 GCC,让 GCC 编译更快 来源:https://peter0x44.github.io/posts/super-gcc/ 不久前,我开始对缩短编译时间感兴趣,并研究了各种方法。 这篇博文的内容是:启用所有我认为能让 gcc 在编译代码时变快的编译器选项,并测量最终获得的性能提升。 ## 如何构建 ``` mkdir build-gcc16 cd build-gcc16 ../gcc-16.1.0/configure \ --prefix="$HOME/opt/gcc16-super" \ --program-prefix=super- \ --enable-languages=c,c++ \ --disable-multilib \ --with-build-config='bootstrap-native bootstrap-lto bootstrap-O3' make profiledbootstrap -j$(nproc) make install-strip ``` 执行 `make profiledbootstrap` 需要等待一段时间。在我的笔记本(AMD Ryzen AI MAX+ PRO 395,16核/32线程,`-j32`)上,实际耗时 72 分钟。 接下来,我将逐一解释各个配置选项及其具体作用。如果你想查看任何 GCC 构建所用的配置选项,使用 `gcc -v` 即可输出。 ## 配置选项详解 **`--with-build-config='bootstrap-native bootstrap-lto bootstrap-O3'`(https://gcc.gnu.org/install/build.html)** `--with-build-config` 从 `gcc/config/*.mk` 中选择一些小的 Makefile 片段,这些片段控制着引导阶段的编译方式。此处涉及的相关片段有: `bootstrap-native`:向编译标志中添加 `-march=native -mtune=native`,使得最终生成的编译器二进制文件针对构建主机进行了优化。不使用此选项时,编译器会以通用 x86-64 代码生成方式构建,无法使用 AVX2、AVX512 等指令集。请注意,这影响的是编译器本身,而非它生成的代码。如果你还希望编译器默认针对*你的*程序输出原生调优的代码,请参考下方的 `--with-arch`/`--with-cpu`/`--with-tune` 选项。 `bootstrap-lto`:为引导阶段启用链接时优化(LTO)。LTO 允许优化器在构建编译器本身时跨越翻译单元边界工作,由于 GCC 是一个从中受益良多的庞大代码库,此选项效果显著。 `bootstrap-O3`:将引导阶段的优化级别从 `-O2` 提升至 `-O3`。 **`make profiledbootstrap`(https://gcc.gnu.org/install/build.html)** 这是一个 make 目标,而非配置选项。它会执行一个基于配置文件引导的优化(PGO)构建:首先构建一个带插桩的编译器,运行一个训练工作负载来收集执行 profile,然后利用这些反馈重新构建。GCC 构建文档描述此过程能生成“更快的编译器二进制文件”,我认为这占了性能提升的很大一部分。 **`--program-prefix=super-`(https://gcc.gnu.org/install/configure.html)** 为安装的程序名添加前缀 `super-`,因此 `gcc` 安装为 `super-gcc`,`g++` 安装为 `super-g++`,以此类推。这样可以让自定义编译器与发行版编译器共存,而不覆盖后者。此选项可选,你可以省略它,通过 PATH 环境变量中程序的顺序来控制调用哪个编译器。 **`--with-cpu=native`/`--with-arch=native`/`--with-tune=native`(https://gcc.gnu.org/install/configure.html)** 你可能也想要这些选项,但我在本次基准测试中并未使用,因为它们会影响编译时间,属于实验中的控制变量。这些选项会改变编译器为*你的*程序生成代码时的*默认值*,对编译器二进制文件本身的构建没有影响。如果你希望编译器默认输出原生调优的代码,从而不必每次都手动传递 `-march=native`,可以添加它们。 **`--enable-languages=c,c++`** 我将语言限制为 C 和 C++ 以减少构建时间。我不使用其他语言前端,但如果你需要,可以自行添加。 **`--disable-multilib`** 跳过构建 32 位目标库。 **`--enable-checking=release`** 如果你将 GCC 发布版本与开发中版本进行比较,值得了解这一点。发布分支默认使用 `--enable-checking=release`(仅包含轻量级断言),而主干默认使用 `--enable-checking=yes,extra`,这会启用更多的内部一致性检查,从而拖慢编译器速度。如果基于主干的 GCC 比预期慢,这很可能就是原因。 你还可以更进一步,使用 `--enable-checking=no` 构建以禁用所有断言,这可能再挤出一点性能。我没有尝试过。 ## 基准测试对比 我基准测试的是编译时间,而非生成代码的运行时间。工作负载是对四个代码库进行干净的并行重建(`-j32`),使用 `hyperfine` 计时(每个工作负载运行 2 次,每次运行之间清理构建目录)。 基准线是 Arch Linux 发行版中的 `gcc` 16.1.1,它已经使用 `bootstrap-lto` 构建。 其配置如下: ``` /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust,cobol --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror --disable-fixincludes ``` 我不完全清楚所有选项的具体作用,但如果还有其他选项对性能有重大影响,请在评论中告诉我。 ## 基准测试结果 | 工作负载 | 发行版 `gcc` | 自建 `super-gcc` | 加速比 | | --- | --- | --- | --- | | GCC 16.1.0 `all-gcc` | 214.982 s | 163.376 s | 1.32x(24.0%) | | binutils 2.46.0 | 28.173 s | 23.900 s | 1.18x(15.2%) | | SDL 3.4.8 | 13.258 s | 11.093 s | 1.20x(16.3%) | | CPython 3.14.5 | 20.627 s | 18.103 s | 1.14x(12.2%) | GCC 编译 GCC 的结果提升最大,很可能因为这就是编译器被 profile 优化时所用的工作负载。其他三个基准测试的提升幅度较小,但也并非微不足道。 ## 声明 此测试在 WSL2 环境下进行,而非直接在 Linux 上运行。每个工作负载我只进行了两次运行,因此存在一定的噪声。 ## 结论 根据工作负载的不同,性能提升幅度从 12% 到 24% 不等,而基准线已经是启用了 LTO 的现代发行版构建。这里额外添加的选项是 `bootstrap-native`、`-O3` 以及 PGO。性能提升很可能来源于此。 今后所有 GCC 发布版我都会这样做——花 72 分钟跑一次构建以换取 12% 的编译速度提升,在我看来非常划算! 你的结果可能会有所不同。如果你尝试了,请留言告诉我是否有帮助(或没有),以及提升幅度是多少。我很好奇,相信其他 GCC 开发者也是如此。

相似文章

未充分利用的性能

Lobsters Hottest

一篇技术博客文章,演示了如何通过LLVM的配置文件引导优化(PGO)在标准-O3和LTO之外显著提升二进制性能,以SQLite作为基准测试。

在 Linux 和 Unix 系统上编译 Emacs 以提升性能的技术指南

Lobsters Hottest

本技术指南提供了在各类 Linux 发行版上从源码编译 Emacs 的详细步骤,旨在通过 CPU 特定指令集和 Wayland 等现代显示协议来优化性能。文中还涵盖了依赖项配置以及微调原生 Lisp 编译器以提升执行速度的相关内容。

当编译器让你惊喜

Lobsters Hottest

Matt Godbolt 探讨了编译器优化如何将 O(n) 求和循环转换为 O(1) 的闭式解,突出了 Clang 和 GCC 如何采用循环展开和数学简化等复杂技术来大幅提升代码性能。

Zig 构建速度正在提升

Mitchell Hashimoto

Zig 0.15 相比 0.14 在编译时性能有显著提升,构建脚本编译时间从约 7 秒降至约 1.7 秒,完整构建时间从 41 秒降至 32 秒,且仍使用 LLVM。本文重点介绍了自托管后端和增量编译方面的进展。