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 参数来判断能不能内联。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Whisper语音识别的实时视频字幕生成 (一): 流式显示视频帧和音频帧

Whishow Whistream(微流)是基于Whisper语音识别的的在线字幕生成工具,支持rtsp/rtmp/mp4等视频流在线语音识别 1. whishow介绍 whishow(微秀)是在线音视频流播放python实现,支持rtsp/rtmp/mp4等输入&…

人工智能——大语言模型

5. 大语言模型 5.1. 语言模型历史 20世纪90年代以前的语言模型都是基于语法分析这种方法,效果一直不佳。到了20世纪90年代,采用统计学方法分析语言,取得了重大进展。但是在庞大而复杂的语言信息上,基于传统统计的因为计算量巨大…

【Docker】Docker概述及引擎

一、docker概述 DevOps DevOps是一种执行标准(思想),主要用于促进开发、测试与运维的整合 容器与虚拟机的区别 最大的区别是,虚拟机中存在独立的硬件系统与操作系统,容器中全部是共享的宿主机中的操作系统与硬件系…

[dvwa] sql injection(Blind)

blind 0x01 low 1’ and length(version()) 6 # syntax: substr(string , from<start from 1>, cut length) 1’ and substr(version(),1,1) ‘5’ # 1’ and substr(version(),2,1) ‘.’ # 1’ and substr(version(),3,1) ‘7’ # 1’ and substr(version(),4,…

酷写写靠谱不 #知识分享#媒体

酷写写是一个值得推荐的论文写作工具&#xff0c;它不仅靠谱而且非常好用。在如今这个信息爆炸的时代&#xff0c;学术界对于论文的要求越来越严格&#xff0c;论文必须具有独创性和高质量才能获得认可。而酷写写的出现&#xff0c;为广大学生和学者提供了一个便捷、高效的写作…

SuperMap三维复杂模型建模之3D极坐标建模——原理篇

作者&#xff1a;超图研究院技术支持中心-于丁 随着SuperMap iDesktop 10i(2021) V10.2.1的上线发布&#xff0c;为进一步拓展全空间数据模型及其分析计算能力&#xff0c;一个新功能“3D极坐标建模”也随着该版本悄然上线。 3D极坐标建模功能实现根据UV参数和数学表达式&…

【Python系列】Jupyter Notebook 中执行 Shell 脚本的方法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【随笔】Git 高级篇 -- 项目里程碑 git tag(二十)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

绝地求生:杜卡迪系列活动集合 各种活动送不停

今天更新已结束&#xff0c;速度上好开冲&#xff01; 春季签到活动&#xff08;第1轮&#xff09; 活动时间 4月9日 - 4月22日 12&#xff1a;00 任务要求 每日登录游戏&#xff08;每日上午10点刷新&#xff09; 活动期间全勤可获得奖励如下 杜卡迪物资箱 (x1) 杜卡迪活…

【C++杂货铺】详解 stack 和 queue

&#x1f308;前言&#x1f308; 欢迎收看本期【C杂货铺】&#xff0c;本期内容将讲解CSTL中stack和queue的内容&#xff0c;其中包含了stack &#xff0c; queue&#xff0c;priority_queue是什么&#xff0c;怎么使用以及模拟实现这些容器。 此外&#xff0c;还将将讲解设计模…

【迅为iMX6Q】开发板 Linux version 6.6.3 SD卡 启动

开发环境 win10 64位 VMware Workstation Pro 16 ubuntu 20.04 【迅为imx6q】开发板&#xff0c; 2G DDR RAM linux-imx 下载 使用 NXP 官方提供的 linux-imx&#xff0c;代码地址为&#xff1a; https://github.com/nxp-imx/linux-imx 使用 git 下载 linux-imx&#xff…

STM32学习和实践笔记(6):自己进行时钟配置的思路

在《STM32学习和实践笔记&#xff08;4&#xff09;: 分析和理解GPIO_InitTypeDef GPIO_InitStructure (d)-CSDN博客》 中&#xff0c;我了解到&#xff0c;在程序执行我们写的main函数之前&#xff0c;实际上先执行了一个汇编语言所写的启动文件&#xff0c;以完成相应的初始…

python爬虫-----爬虫解析—xpath(第十八天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

Day:004(4) | Python爬虫:高效数据抓取的编程技术(数据解析)

XPath工具 浏览器-元素-CtrlF 浏览器-控制台- $x(表达式) Xpath helper (安装包需要科学上网) 问题 使用离线安装包 出现 程序包无效 解决方案 使用修改安装包的后缀名为 rar&#xff0c;解压文件到一个文件夹&#xff0c;再用 加载文件夹的方式安装即可 安装 python若使用…

功能测试_验证qq账号的合法性

案例&#xff1a;验证qq账号的合法性&#xff08;要求&#xff1a;6-10位的自然数&#xff09; 使用等价类设计用例案例&#xff1a; 步骤&#xff1a; 1:明确需求&#xff1a;qq账号的合法性 2:划分等价类&#xff1a;有效等价类、有效取值、无效等价类、无效取值 3&…

风电场智能化转型基于ARM工控机的HDMI数据实时监控显示

全球能源结构不断调整的大背景下&#xff0c;智能电网、太阳能发电、风能发电等清洁能源领域正经历着一场由技术创新引领的深刻变革。在这场变革中&#xff0c;ARM架构的工控机凭借其出色的性能、低功耗及高度可定制化的特点&#xff0c;正在成为能源管理系统的核心组件&#x…

ModStartCMS(支持Laravel 9)v8.3.0

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

tailwindcss在manoca在线编辑智能感知

推荐一下monaco-tailwindcss库&#xff0c;它实现在monaco-editor网页在线编辑器中对tailwindcss的智能感知提示&#xff0c;在利用tailwindcss实现html效果布局。非常的方便。 生成CSS

python简单读取和索引.nc文件(气象小白入门版)

一、总代码 #数据下载&#xff0c;这里下载的是NCEP的气压数据&#xff0c;在命令行运行代码即可 #wget -P /mnt/g/st_touchfish_py/data ftp://ftp.cdc.noaa.gov/Datasets/ncep.reanalysis.derived/pressure/air.mon.mean.ncimport xarray as xr import pandas as pd import …