From 6e0e492e1229b22acdc8161efd12500a0e09e67e Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Tue, 15 Nov 2022 13:37:42 -0500 Subject: [PATCH] cmd/compile/internal/pgo: count only the last two frames as a call edge Currently for every CPU profile sample, we apply its weight to all call edges of the entire call stack. Frames higher up the stack are unlikely to be repeated calls (e.g. runtime.main calling main.main). So adding weights to call edges higher up the stack may be not reflecting the actual call edge weights in the program. This CL changes it to add weights to only the edge between the last two frames. Without a branch profile (e.g. LBR records) this is not perfect, but seems more reasonable. Change-Id: I0aee75cc608a152adad41c51120b661a6c542283 Reviewed-on: https://go-review.googlesource.com/c/go/+/450915 Run-TryBot: Cherry Mui TryBot-Result: Gopher Robot Reviewed-by: Austin Clements --- src/cmd/compile/internal/pgo/graph.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/pgo/graph.go b/src/cmd/compile/internal/pgo/graph.go index 203cc618ca1..a2cf18f936a 100644 --- a/src/cmd/compile/internal/pgo/graph.go +++ b/src/cmd/compile/internal/pgo/graph.go @@ -270,7 +270,17 @@ func newGraph(prof *profile.Profile, o *Options) *Graph { residual := false // Group the sample frames, based on a global map. - for i := len(sample.Location) - 1; i >= 0; i-- { + // Count only the last two frames as a call edge. Frames higher up + // the stack are unlikely to be repeated calls (e.g. runtime.main + // calling main.main). So adding weights to call edges higher up + // the stack may be not reflecting the actual call edge weights + // in the program. Without a branch profile this is just an + // approximation. + i := 1 + if last := len(sample.Location) - 1; last < i { + i = last + } + for ; i >= 0; i-- { l := sample.Location[i] locNodes := locationMap.get(l.ID) for ni := len(locNodes) - 1; ni >= 0; ni-- {