Go - Save up to 14% CPU in Production with Profile-Guided Optimization
このページは日本語には対応しておりません。随時翻訳に取り組んでいます。翻訳に関してご質問やご意見ございましたら、お気軽にご連絡ください。
Overview
Starting with [Go 1.21][1], the Go compiler supports profile-guided optimization (PGO).
PGO enables additional optimizations on code identified as hot by CPU profiles of production workloads. This is compatible with [Datadog Go Continuous Profiler][2] and can be used for production builds.
How PGO works
Here are some key points about how PGO works:
- Building a Go program with PGO enabled causes the compiler to look for a pprof CPU profile named
default.pgo
and use it to produce a more optimized binary. - Typical programs should see a 2-14% decrease in CPU time after optimization. PGO remains under active development, and future versions of Go aim to achieve even greater CPU savings. Datadog is [actively supporting this initiative][3].
- PGO produces the best results when using representative profiles. However, using non-representative or old profiles (from previous versions of the software) is not expected to result in slower binaries compared to not using PGO.
- Using a profile from a PGO optimized application is not expected to cause optimization/deoptimization cycles. This is referred to as iterative stability.
For more information, see the [Go PGO documentation][4].
Enabling PGO
PGO is a standard Go compiler option that you can use by manually downloading profiles from Datadog. Datadog built a tool, datadog-pgo
to help you enable PGO on all services, using the latest and most representative profiles.
datadog-pgo
is in public beta.
To enable PGO using the datadog-pgo
tool:
Create a dedicated API key and an application key scoped to at least continuous_profiler_pgo_read
as described in [API and Application Keys][5].
Set DD_API_KEY
, DD_APP_KEY
, and DD_SITE
with the environment secret mechanism of your CI provider.
Run datadog-pgo
before your build step.
For example, for a service foo
that runs in prod
and has its main package in ./cmd/foo
, you should add this step:
go run github.com/DataDog/datadog-pgo@latest "service:foo env:prod" ./cmd/foo/default.pgo
The Go toolchain automatically picks up any default.pgo
file in the main package, so you don’t need to modify your go build
step.
See the [datadog-pgo GitHub repository][6] for more details.
Checking if PGO is enabled
To check where PGO is enabled, search for [Go profiles without pgo tag set to true][7].
The pgo
tag was implemented in dd-trace-go 1.61.0, so any profiles prior to this version will not have pgo:false
.
Further reading
[1]:
https://tip.golang.org/doc/go1.21
[2]: /ja/profiler/enabling/go
[3]:
https://github.com/golang/go/issues/65532
[4]:
https://go.dev/doc/pgo
[5]: /ja/account_management/api-app-keys
[6]:
https://github.com/DataDog/datadog-pgo?tab=readme-ov-file#getting-started
[7]:
https://app.datadoghq.com/profiling/explorer?query=runtime%3Ago%20-pgo%3Atrue%20&viz=stream