当前位置: 首页 > 后端技术 > Java

什么是PGO,为什么它能让Go变得更快更强?

时间:2023-04-01 22:02:21 Java

大家好,我是炸鱼。Go1.20即将发布。最近很多大佬提到了一个关键词PGO,说是大大提升了,很猛……让我愣了一下,不由得想这是什么东西?今天炸鱼就跟大家一起学习。快速理解什么是PGO是Profile-guidedoptimization(PGO),翻译过来就是配置文件引导的优化。也称为:profile-directedfeedback(PDF)feedback-directedoptimization(FDO)PGO是计算机编程中的一种编译器优化技术,它使用分析来提高程序运行时性能。也就是说,它可以提高Go运行时的性能。这种优化是一种通用技术,不局限于某种语言。例如:常用的Chrome浏览器,从53版开始,64位版本的Chrome启用了PGO,54版开始启用了32位版本,也使用了MicrosoftVisualC++。AutoFDO优化了PGO,直接提升数据中心C/C++程序性能5-15%(不改动业务代码)。这个优化结果听了很振奋人心。如何优化PGO《Intel Developer Guide and Reference》对PGO的优化和过程有一个基本的介绍。以下内容与您分享。PGO通过减少代码大小、减少分支预测错误和重组代码布局来减少指令缓存问题,从而提高应用程序性能。并向编译器提供有关应用程序最常执行区域的信息。通过了解这些领域,编译器在优化应用程序时能够更具选择性和针对性。PGO由三个阶段组成。如下图所示:检测程序。编译器根据您的源代码和特定于编译器的代码创建并链接检测程序。运行检测的可执行文件。每次执行插桩代码时,插桩程序都会生成一个动态信息文件,供最后编译使用。最后编译。第二次编译时,动态信息文件合并为一个摘要文件。使用此文件中的摘要信息,编译器会尝试优化程序中最常运行的路径以供执行。这就是PGO优化的基本过程。新提案背景提案作者(CherryMui、AustinClements、MichaelPratt)提议向GoGC工具链添加对Profile-GuidedOptimization(PGO)的支持,这将允许工具链根据运行时信息执行特定于应用程序和工作负载的执行.优化。说明我想在不更改业务代码的情况下提高性能。PGO做什么需要用户参与收集配置文件并将其反馈到构建过程中进行优化。这是个大问题。最符合这一要求的是pprof。最终确定Go团队将根据runtime/pprof获取所需的配置文件来完成PGO。因为它符合:低采样开销、强多系统兼容性、Go标准和广泛使用的基准测试。也就是说,有了runtime/pprof生成的profile,就可以做PGO了!支持到什么程度?第一版PGO会先支持pprofCPU,直接读取pprofCPUprofile文件完成优化。预计在Go1.20发布预览版。在Go工具链上,-pgo=将被添加到gobuild子命令中,以明确指定用于PGO构建的配置文件的位置。可能有同学会说,明确指定太麻烦了吧?Go团队也考虑到了这一点……你只需要设置为:-pgo=auto,它就会自动读取主目录下的profile文件,很香!如果不需要,可以直接-pgo=off完全关闭PGO。Go1.20实现PGO预览版,配置默认关闭,成熟后默认为auto。从哪儿开始?Go团队将首先专注于Go编译器的开发。毕竟,这是一切的开始。后面我们会在cmd/go做一些简单的支持。PGO的第一个动手方向是:函数内联。这被认为是最具成本效益的。未来还会包括:去虚拟化(devirtualization,一种编译器优化策略)、特定泛型函数的模板化、基本块排序和函数布局。它甚至会在后面用于改善内存行为,例如改善转义行为和内存分配。看看这个PGO的未来前景,这个大饼,感觉画的又大又圆(远)。。。进阶实践以下是来自@FredericBranczyk的文章《Exploring Go's Profile-Guided Optimizations》,提前使用PGO对函数由GoLian官方开发的,成为尝鲜者。步骤如下:先拉取实现的Go源码,编译导入。以下代码:gitclonehttps://go.googlesource.com/gocdgogitfetchhttps://go.googlesource.com/gorefs/changes/63/429863/3&&gitcheckout-bchange-429863FETCH_HEADcdsrc。/all.bashcd..exportPATH="$(pwd)/bin:$PATH"#或者添加你的??bashrc/zshrc路径进入PGO的内联测试代码:cdsrc/cmd/compile/internal/test/testdata/pgo/inline提前准备,生成pprofcpuprofile文件:gotest-oinline_hot.test-bench=。-cpuprofileinline_hot.pprof完成准备动作后。我们进行了两项测试:一项没有PGO,一项有PGO,以进行比较。不使用PGO时:gotest-run=none-tags=''-timeout=9m0s-gcflags="-m-m"2>&1|grep"caninline"./inline_hot.go:15:6:caninlineDwithcost7as:func(uint)int{returnint((i+(wSize-1))>>lWSize)}./inline_hot.go:19:6:可以将N与成本20内联为:func(uint)*BS{bs=&BS{...};returnbs}...使用PGO时:gotest-run=none-tags=''-timeout=9m0s-gcflags="-m-m-pgoprofileinline_hot.pprof"用于下面的对比:gotest-oinline_hot.test-bench=。-cpuprofileinline_hot.pprof-count=100>without_pgo.txtgotest-oinline_hot.test-bench=.-gcflags="-pgoprofileinline_hot.pprof"-count=100>with_pgo.txtbenchstatwithout_pgo.txtwith_pgo.txtname旧时间/op新时间/opdeltaA-10960μs±2%950μs±1%-1.05%(p=0.000n=98+83)from综上所述,引入PGO后有1%的性能提升。当然,这只是一小段测试代码。不同的程序会有不同的结果。总结PGO是一种编译器优化技术,可以在不改变业务代码的情况下提高你的应用程序的性能。在GoPGO中,会依赖runtime/pprof生成的profile来完成(需要修改),也算是一个不错的系列。另外,从需求的角度来看,这种优化似乎来自开发同学的兴趣优化。官方并没有指出是什么用户痛点导致了这个功能的开发。但是,如果以后遇到一些需要进一步优化的Go程序,PGO会是一个不错的选择。毕竟不用改业务代码。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的原因与设计思维Go语言进阶之旅:进一步深入-depthGo源代码推荐阅读Gofor循环有时真的很棘手。..Go十年,终于想起统一日志库!仅当err!=nil时才去?不对,把这些优雅的搬运姿势分享给你!