Golang使用PGO优化程序性能


文章目录

    • 参考文章
    • PGO是什么
    • 使用PGO的好处
    • PGO做了什么
      • 热函数内联
        • 什么是内联
        • 内联的好处
        • Go默认的内联策略
        • 查看内联预算
        • PGO的热函数内联
      • 去虚拟化调用
      • 指令高速缓存
    • PGO有什么缺点
      • 可执行程序变大
      • 构建时间变长
    • PGO怎么使用
      • 典型的工作流程
      • 收集CPU配置文件
      • 生产环境启动PGO
      • 代码改动重新生成CPU配置文件
    • PGO的未来
    • 个人看法
    • QA
      • Q1 PGO是否可以优化标准包和依赖的包
      • Q2 CPU配置文件不当是否会使我的程序比没有 PGO 的速度慢?
      • Q3 怎么保证收集到公正的CPU配置文件
      • Q4 不同运行环境下如何使用PGO

参考文章

PGO介绍:
https://andrewwphillips.github.io/blog/pgo.html
生成profile配置文件:
https://andrewwphillips.github.io/blog/flame-graphs.html#generating-cpu-profiles

提案:Go 的配置文件引导优化(PGO)的设计和实现:
https://go.googlesource.com/proposal/+/master/design/55022-pgo-implementation.md

go官方文档使用PGO:
https://go.dev/doc/pgo#:~:text=Collecting%20representative%20profiles%20from%20production

PGO:为你的go程序提效5%:
https://colobu.com/2023/09/13/pgo/

PGO是什么

引入官方的说法:https://go.dev/doc/pgo#merging-profiles
从 Go 1.20 开始,Go 编译器支持配置文件引导优化 (PGO) 以进一步优化构建。
Profile-guided optimization (PGO)。配置文件引导优化 (PGO),也称为反馈导向优化 (FDO),是一种编译器优化技术,它将应用程序的代表性运行中的信息(配置文件)反馈回编译器,以供下一次构建应用程序使用。它使用该信息做出更明智的优化决策。例如,编译器可能决定更积极地内联配置文件指示频繁调用的函数。
在Go中,编译器使用CPU pprof配置文件作为输入配置文件,例如来自runtime/pprof或net/http/pprof。
从 Go 1.22 开始,一组代表性 Go 程序的基准测试表明,使用 PGO 进行构建可将性能提高约 2-14%。

自Go 1.20版本引入PGO(profile-guided optimization)后,PGO这种优化技术带来的优化效果就得到了持续的提升:Go 1.20实测性能提升仅为1.05%;Go 1.21版本发布时,官方的数据是2%~7%,而Go 1.21编译器自身在PGO优化过后编译速度提升约6%。
在Go 1.22中,官方给出的数字则是2%~14%,这14%的提升想必是来自Google内部的某个实际案例。

使用PGO的好处

提升性能,降低成本。
在 Google 服务器上运行的大部分代码都是使用 PGO 构建的。当你考虑到(我的估计)所有这些服务器的电费每年必须接近(如果不超过)10 亿美元时,PGO 每年可能至少为 Google 节省数千万美元。所以从经济上来说这是有道理的。

PGO做了什么

热函数内联

什么是内联

所谓内联,指的是编译期间,直接将调用函数的地方替换为函数的实现,它可以减少函数调用的开销以提高程序的性能。

内联的好处
  1. 解除函数调用的开销,以空间换时间;
  2. 支持编译器更有效地应用其他优化策略。

Go默认的内联策略
  1. 函数足够简单,当解析AST时,Go申请了80个节点作为内联的预算。每个节点都会消耗一个预算。函数的开销不能超过这个预算;
  2. 不能包含闭包,defer,recover,select;
  3. 不能以 go:noinline 或 go:unitptrescapes 开头;
  4. 必须有函数体;
  5. 其他等复杂要求,详细可见src/cmd/compile/internal/gc/inl.go相关内容。我们可以使用 gcflags 参数来判断能不能内联。

查看内联预算

关于内联的预算,可以使用编译命令-gcflags=-m=2查看详细的优化决策,例如:
可以看到哪个函数内联了,哪个没有内联,以及内联的成本。

go build -gcflags=-m=2 inl.go 
#/inl.go:3:6: can inline small with cost 7 as: func() string { s := "hello, world!"; return s }
./inl.go:8:6: cannot inline large: function too complex: cost 82 exceeds budget 80
./inl.go:38:6: can inline main with cost 68 as: func() { small(); large() }
./inl.go:39:7: inlining call to small func() string { s := "hello, world!"; return s }

当使用-gcflags=-m=2这个命令时,会指示Go编译器输出更详尽的优化决策信息。这个-m标志被用来控制编译器的内联和逃逸分析信息的输出。在这个上下文中,-m后跟等号和一个数字表示详细级别。
● -m:显示出哪些函数被内联。
● -m=2或者更高的数字,如-m=3,会显示更多的信息,包括为什么某些函数没有被内联(比如说,函数过于复杂)以及变量逃逸分析的结果(比如说,哪些变量被移动到了堆上)。

PGO的热函数内联

如果调用次数较多的函数(所谓的函数)稍微超出内联预算,则可能不会内联它们。
PGO 做了几件事来使内联更加有效。首先,它增加了热点函数的内联预算
PGO 避免内联 CPU 配置文件显示为冷函数的函数。同样,这减少了不必要的代码膨胀。

去虚拟化调用

通过接口调用方法比直接方法/函数调用慢。CPU配置文件可以显示调用的具体类型是什么,从而在编译的时候,直接优化为具体类型的调用:

type I interface { f() }
...var i I...i.f()# PGO优化# 热路径if a, ok := i.(A); ok {a.f() // direct call} else {i.f()}

指令高速缓存

CPU 配置文件允许编译器通过代码查找常用执行路径或路径。编译器将对函数内的代码块重新排序,并且(稍后在构建过程中)链接器将调整函数的位置,从而确定将它们加载到指令内存中的位置。
image.png

PGO有什么缺点

可执行程序变大

由于额外的函数内联,PGO 可能会产生稍大的二进制文件。

构建时间变长

启用 PGO 构建可能会导致包构建时间显着增加。其中最值得注意的部分是 PGO 配置文件适用于二进制文件中的所有包,这意味着首次使用配置文件需要重建依赖关系图中的每个包。这些构建像其他构建一样被缓存,因此使用相同配置文件的后续增量构建不需要完全重建。
例如:https://github.com/golang/go/issues/58102 构建时间可能会增加好几倍,当然go官方团队也在致力于解决这个问题。

PGO怎么使用

典型的工作流程

  1. 构建并发布初始二进制文件(不含 PGO)。
  2. 从生产中收集配置文件。
  3. 当需要发布更新的二进制文件时,从最新源构建并提供生产配置文件。
  4. 转到2

收集CPU配置文件

明确不开启PGO的情况下,例如go build -pgo=off,使用pprof进行CPU配置收集,收集结果为default.pgo。建议是收集生产环境的CPU配置文件更为精准,当然如果可以保证测试/仿真环境和生产环境一致的话,在测试/仿真环境收集也是OK的。

生产环境启动PGO

go1.21之后默认开启了PGO,也可以在编译的时候手动设置。
例如:

  1. 开启PGO: go build -pgo=auto
  2. 设置PGO配置文件路径: go build -pgo=/tmp/foo.pprof

代码改动重新生成CPU配置文件

如果无法评估迭代对于CPU配置文件的影响,建议是发布的时候重新收集CPU配置,参考上面的流程。 go官方建议PGO文件可以提交到版本库里面,方便对比和管理。

PGO的未来

有很多“微观”优化的机会。例如,如果在堆上分配的变量不需要在热路径中转义,则该变量可以在堆栈上分配,并且仅在采用冷路径时才移动到堆。
一件重要的事情(随着泛型的使用越来越多)是称为模板的功能。当在热路径中调用泛型函数时,PGO 可以确定类型参数,并专门为该类型生成代码(甚至可能在热调用站点内联它!)
未来要迭代的方向:https://github.com/golang/go/issues/62463

个人看法

对于GO程序来说,大家认为整体还是比较高效的,只是相对于c和rust来说性能确实有差距,可能达到25%的性能差距,但是GO的易用性和生态弥补了这一缺陷。只是谁又不想让自己的程序快一点,占用资源少一点呢?

对小型项目来说,关注新技术即可,没必要强行上PGO。毕竟有一定的构建成本,且小型项目对性能和成本不敏感。而对于大型项目或者大型互联网公司来说,例如字节,B站这些,别说14%的优化了,2%的优化都值得正确,可能带来的是千万级的成本节省。

QA

Q1 PGO是否可以优化标准包和依赖的包

是的。 Go中的PGO适用于整个程序。所有包都会重新构建,以考虑潜在的配置文件引导优化,包括依赖项中的包。这意味着应用程序使用依赖项的独特方式会影响应用于该依赖项的优化。

Q2 CPU配置文件不当是否会使我的程序比没有 PGO 的速度慢?

不应该。虽然不代表生产行为的配置文件将导致应用程序冷部分的优化,但它不应该使应用程序热部分变慢。如果您遇到 PGO 导致性能比禁用 PGO 更差的程序,请在go.dev/issue/new提交问题。

Q3 怎么保证收集到公正的CPU配置文件

  1. 在高峰期,平稳期或者任何时间,都可以收集CPU配置文件
  2. 合并收集到的多个配置文件:
$ go tool pprof -proto a.pprof b.pprof > merged.pprof

这种合并实际上是输入中样本的简单求和,无论配置文件的墙持续时间如何。因此,当分析应用程序的小时间片(例如,无限期运行的服务器)时,您可能希望确保所有配置文件具有相同的墙持续时间(即,收集所有配置文件 30 秒)。否则,具有较长墙持续时间的配置文件将在合并的配置文件中过多表示。

Q4 不同运行环境下如何使用PGO

  1. 相同的CPU配置文件,可以在linux和windows上的应用程序使用。对于大多数应用程序来说,绝大多数代码是平台无关的,因此这种形式的退化是有限的。
  2. 为不同运行环境生成独有的CPU配置。代价就是增加管理负担。

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Electron+React 搭建桌面应用

创建应用程序 创建 Electron 应用 使用 Webpack 创建新的 Electron 应用程序: npm init electron-applatest my-new-app -- --templatewebpack 启动应用 npm start 设置 Webpack 配置 添加依赖包,确保可以正确使用 JSX 和其他 React 功能&#xff…

3.1 基本形式 机器学习

从本章本节开始就开始正式介绍机器学习的算法了!我们首先登场的是---------线性模型。 w可以理解为权重,我们的x就是我们的样本点的各个特征数值,最后输出模型f(x)。其代表我们把样本点带入,以二分类为例&a…

厂房起火3D消防灭火安全救援模拟演练

深圳VR公司华锐视点依托前沿的VR虚拟现实制作、三维仿真和图形图像渲染技术,将参训者带入栩栩如生的火灾现场。佩戴VR头盔,参训者将真切体验火势蔓延的紧张与危机,身临其境地感受火灾的恐怖。 并且消防安全VR虚拟现实演练系统精心模拟了住宅、…

修复 Windows 上的 PyTorch 1.1 github 模型加载权限错误

问题: 在 Windows 计算机上执行示例 github 模型加载时,生成了 master.zip 文件的权限错误(请参阅下面的错误堆栈跟踪)。 错误堆栈跟踪: 在[4]中:en2de = torch.hub.load(pytorch/fairseq, transformer.wmt16.en-de, tokenizer=moses, bpe=subword_nmt) 下载:“https://…

uniapp 卡片勾选

前言 公司的app项目使用的uniapp&#xff0c;项目里有一个可勾选的卡片功能&#xff0c;效果图如下&#xff1a; 找了一圈没找到什么太好的组件&#xff0c;于是就自己简单写了一个&#xff0c;记录一下。避免以后还会用到 代码 <template><view class"card-…

ELK 企业级日志分析系统 简单介绍

目录 一 ELK 简介 1&#xff0c; elk 是什么 2&#xff0c;elk 架构图 3&#xff0c;elk 日志处理步骤 二 Elasticsearch 简介 1&#xff0c; Elasticsearch 是什么 2&#xff0c; Elasticsearch 的核心概念 3&#xff0c; Elasticsearch 的原理 三 Logstas…

labview技术交流-如何判断一个数是否为质数

问题起源 如何判断一个数是否为质数&#xff0c;其实并不难&#xff0c;只要你知道质数的定义&#xff0c;按照它的定义去编写代码就可以了。但是没有思路的人可能就会一直找不到方向&#xff0c;所以我就简单介绍一下。 还有我想吐槽的点&#xff0c;labview本来就是很小众的语…

Harmony鸿蒙南向驱动开发-SPI

SPI即串行外设接口&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线。SPI是由Motorola公司开发&#xff0c;用于在主设备和从设备之间进行通信。 运作机制 在HDF框架中&#xff0c;SPI的接口适配模…

【MATLAB源码-第6期】基于matlab的QPSK的误码率BER和误符号率SER仿真。

1、算法描述 QPSK&#xff0c;有时也称作四位元PSK、四相位PSK、4-PSK&#xff0c;在坐标图上看是圆上四个对称的点。通过四个相位&#xff0c;QPSK可以编码2位元符号。图中采用格雷码来达到最小位元错误率&#xff08;BER&#xff09; — 是BPSK的两倍. 这意味著可以在BPSK系统…

瑞山集团携手数环通iPaaS,实现ERP与CRM无缝对接

01 客户背景 瑞山集团位于粤港澳大湾区核心商圈----佛山市&#xff0c;是一家致力于各种新型材料添加剂应用推广&#xff0c;集科研、销售和服务于一身的新材料企业&#xff0c;产品覆盖了塑料黏胶剂、水性涂料、3D打印材料、电子材料、纳米材料等各种行业。 公司旗下拥有几间不…

计算机视觉 | 基于 ORB 特征检测器和描述符的全景图像拼接算法

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目实现了基于 ORB 特征检测器和描述符的全景图像拼接算法&#xff0c;能够将两张部分重叠的图像拼接成一张无缝连接的全景图像。 文章目录 一、随机抽样一致算法二、功能实现三、代码解析四、效果展示五、完整代码 一、随机…

【面试题】微博、百度等大厂的排行榜如何实现?

背景 现如今每个互联网平台都会提供一个排行版的功能&#xff0c;供人们预览最新最有热度的一些消息&#xff0c;比如百度&#xff1a; 再比如微博&#xff1a; 我们要知道&#xff0c;这些互联网平台每天产生的数据是非常大&#xff0c;如果我们使用MySQL的话&#xff0c;db实…

第十一届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

第十一届蓝桥杯大赛软件赛省赛C/C 大学 B 组 文章目录 第十一届蓝桥杯大赛软件赛省赛C/C 大学 B 组1、字串排序2、门牌制作3、既约分数4、蛇形填数5、跑步锻炼6、七段码7、成绩统计8、回文日期9、子串分值和10、平面切分 1、字串排序 // 转载博客链接 https://blog.csdn.net/we…

【QT+QGIS跨平台编译】175:【QGIS_App跨平台编译】—【错误处理:未定义的class APP_EXPORT】

点击查看专栏目录 文章目录 一、未定义的class APP_EXPORT二、错误处理 一、未定义的class APP_EXPORT 报错信息&#xff1a; 二、错误处理 第18行增加&#xff1a; #include "qgis_app.h"

潍微科技-水务信息管理平台 ChangePwd SQL注入漏洞复现

0x01 产品简介 水务信息管理平台主要帮助水务企业实现水质状态监测、管网运行监控、水厂安全保障、用水实时监控以及排放有效监管,确保居民安全稳定用水、环境有效保护,全面提升水务管理效率。由山东潍微科技股份有限公司研发,近年来,公司全力拓展提升水务、水利信息化业务…

uniapp区分app、h5、小程序

APP端 标签内 <!-- #ifdef APP-PLUS --><view> APP端 </view> <!-- #endif --> JSCSS内 /*#ifdef APP-PLUS*/console.log(APP端) /*#endif*/ H5端 标签内 <!-- #ifdef H5 --><view> H5端 </view> <!-- #endif --> JSC…

【STM32篇】DRV8425驱动步进电机

【STM32篇】4988驱动步进电机_hr4988-CSDN博客 在上篇文章中使用了HR4988实现了步进电机的驱动&#xff0c;在实际运用过程&#xff0c;HR4988或者A4988驱动步进电机会存在电机噪音太大的现象。本次将向各位友友介绍一个驱动简单且非常静音的一款步进电机驱动IC。 1.DRV8425简介…

TRON x HTX DAO 2024 香港之夜:共建香港元宇宙金融自由港

4月9日&#xff0c;由波场TRON主办&#xff0c;HTX DAO协办的“TRON x HTX DAO 2024 香港之夜”主题活动在香港盛大举行。多位参与HTX DAO生态建设的项目方代表、委员会成员、知名KOL等出席并就HTX DAO发展及加密业态进行演讲。 活动现场&#xff0c;波场TRON创始人孙宇晨通过视…

详解Spring event如何优雅实现系统业务解耦、实现原理及使用注意项

1.概述 在我们平时的项目业务系统开发过程中&#xff0c;一个需求功能的业务逻辑经常出现主线业务和副线业务之分。比如&#xff0c;在当下移动端电商app进行注册账号操作&#xff0c;注册成功之后会发送短信、邮箱、站内信等通知&#xff0c;发放红包活动抵用券&#xff0c;推…

LinuxAndroid: 旋转编码器input输入事件适配(旋转输入)

rk3588s: 旋转编码器input输入事件适配 基于Android 12 kernel-5.10版本 参考文档&#xff1a; https://blog.csdn.net/szembed/article/details/131551950 Linux 输入设备调试详解&#xff08;零基础开发&#xff09;Rotary_Encoder旋转编码器驱动 通用GPIO为例 挂载input输…