t;
性能分析
现在我们来采集一个profile文件,再使用PGO来重新构建服务,看看性能能提升多少。
在main.go
中,我们导入了net/http/pprof
包,它会自动为服务器添加一个/debug/pprof/profile
地址,用于获取CPU分析数据。
通常情况下,我们都是从生产环境中收集性能分析数据,以便编译器能够获取在实际生产环境中的行为情况。但这个示例没有一个真实的“生产”环境,我们将创建一个简单的程序来生成负载,同时收集性能分析数据。将该程序的源码复制到load/main.go
,并启动负载生成器(确保服务器仍在运行!)。
$ go run example.com/markdown/load
下载性能分析文件:
$ curl -o cpu.pprof "http://localhost:8080/debug/pprof/profile?seconds=30"
下载完成后,关闭服务。
启用PGO
我们可以使用go build
命令的-pgo
标志要求Go工具链使用PGO进行构建。-pgo
标志可以接受以下两种参数:
- 指定要使用的性能分析文件的路径
- 使用"auto",它将使用主包目录中的default.pgo文件
我们建议将default.pgo
性能分析文件提交到你的代码仓库中。将性能分析文件与源代码放在一起,可以确保用户只需获取代码仓库(无论是通过版本控制系统还是通过go get
命令),就能自动获得性能分析文件,并且构建过程仍然可重现。在Go 1.20中,默认的-pgo
选项是off
,因此用户仍需要添加-pgo=auto
选项,但预计将来的Go版本将把默认值改为-pgo=auto
,这样任何构建该二进制文件的人都将获得PGO的好处。
构建:
$ mv cpu.pprof default.pgo
$ go build -pgo=auto -o markdown.withpgo
性能对比
我们将使用一个基于Go的基准测试版本的负载生成器来评估PGO对性能的影响。将这个基准测试的代码复制到load/bench_test.go文件中。
首先没有使用PGO的情况下进行测试:
$ ./markdown.nopgo
进行测试:
$ go test example.com/markdown/load -bench=. -count=100 -source ../README.md > nopgo.txt
然后启用PGO:
$ ./markdown.withpgo
进行测试:
$ go test example.com/markdown/load -bench=. -count=100 -source ../README.md > withpgo.txt
运行结束后进行结果对比:
$ go install golang.org/x/perf/cmd/benchstat@latest
$ benchstat nopgo.txt withpgo.txt
goos: linux
goarch: amd64
pkg: example.com/markdown/load
cpu: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
│ nopgo.txt │ withpgo.txt │
│ sec/op │ sec/op vs base │
Load-8 445.1µ ± 4% 408.6µ ± 2% -8.21% (p=0.000 n=100)
新版本大约快了8.2%!在Go 1.20
中,通过启用PGO,可以获得2%到4%的CPU使用率提升。性能分析文件包含了关于应用程序行为的丰富信息,而Go 1.20
仅仅开始利用这些信息进行内联优化。未来的发布版本将继续改进性能,因为编译器的更多部分将利用PGO带来的好处。
原文中效率提升了2.6%
文中的代码可以在这里找到。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意