传统编译 vs PGO 编译

举报
黄生 发表于 2026/10/08 17:24:30 2026/10/08
【摘要】 PGO = Profile-Guided Optimization,剖面引导优化,也叫"反馈驱动优化"。让编译器先看程序真实怎么跑,再决定怎么优化。 传统编译 vs PGO 编译传统编译:编译器只能靠静态分析猜。比如遇到一个 if-else,它不知道哪个分支更常走,只能凭经验猜,猜错了代码布局就不理想。PGO 编译:分两步走——采数:先编译一个带计数功能的版本,跑一遍典型业务负载,记录下"哪...

PGO = Profile-Guided Optimization,剖面引导优化,也叫"反馈驱动优化"。让编译器先看程序真实怎么跑,再决定怎么优化。

传统编译 vs PGO 编译

传统编译:编译器只能靠静态分析猜。比如遇到一个 if-else,它不知道哪个分支更常走,只能凭经验猜,猜错了代码布局就不理想。

PGO 编译:分两步走——

  1. 采数:先编译一个带计数功能的版本,跑一遍典型业务负载,记录下"哪个函数最热"“哪个分支走得最多”“哪个循环迭代多少次”。
  2. 重编译:把这份 profile 数据喂给编译器,编译器据此做决策:
    • 把热函数排在一起,提高指令缓存命中
    • 热分支直连,冷分支挪远
    • 对热函数做更激进的优化(如内联、向量化)
    • 寄存器分配优先照顾热路径

和 BOLT 的关系

两者思路一样,都是"用运行时数据指导优化",但作用层次不同:

PGO BOLT
操作对象 源码/编译中间表示 已编译的二进制
需要源码 需要 不需要
介入时机 编译期 链接之后
典型提升 5-15% 在 PGO 基础上再 5-10%

所以它们可以叠加:先 PGO 编译,再用 BOLT 对产物二次重排。很多大型项目(如 MySQL、MongoDB、LLVM 自身)就是这么做的。

PGO 的两种采数方式

  • 插桩式 PGO:编译时加 -fprofile-generate,跑负载生成 .gcda 计数文件,再用 -fprofile-use 重编译。精度高,但二进制有开销。
  • 采样式 PGO:用 perf 等工具采样,生成 profile,再用 -fprofile-use 重编译。开销低,精度略差,但适合生产环境。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。