]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/pgo: count only the last two frames as a call edge
authorCherry Mui <cherryyz@google.com>
Tue, 15 Nov 2022 18:37:42 +0000 (13:37 -0500)
committerCherry Mui <cherryyz@google.com>
Thu, 17 Nov 2022 20:52:28 +0000 (20:52 +0000)
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 <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/pgo/graph.go

index 203cc618ca17c3b5fbd3208484658a80e88fd988..a2cf18f936aea552ca71e289ba62e1b62def4fee 100644 (file)
@@ -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-- {