aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/inline
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2022-11-01 12:33:58 -0400
committerCherry Mui <cherryyz@google.com>2022-11-03 16:00:30 +0000
commitb07e845e764806fa888cb4e99c8ace4625f0472f (patch)
tree551c84bb280ba74ad025c8555a572b1576170f7e /src/cmd/compile/internal/inline
parent932330fdbf669e28748227148f3f633620a5a300 (diff)
downloadgo-b07e845e764806fa888cb4e99c8ace4625f0472f.tar.xz
cmd/compile: use CDF to determine PGO inline threshold
Currently in PGO we use a percentage threshold to determine if a callsite is hot. This CL uses a different method -- treating the hottest callsites that make up cumulatively top X% of total edge weights as hot (X=95 for now). This default might work better for a wider range of profiles. (The absolute threshold can still be changed by a flag.) For #55022. Change-Id: I7e3b6f0c3cf23f9a89dd5994c10075b498bf14ee Reviewed-on: https://go-review.googlesource.com/c/go/+/447016 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/cmd/compile/internal/inline')
-rw-r--r--src/cmd/compile/internal/inline/inl.go52
1 files changed, 46 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 98bfb4e382..3f7ad34af3 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -29,6 +29,7 @@ package inline
import (
"fmt"
"go/constant"
+ "sort"
"strconv"
"strings"
@@ -69,7 +70,13 @@ var (
inlinedCallSites = make(map[pgo.CallSiteInfo]struct{})
// Threshold in percentage for hot callsite inlining.
- inlineHotCallSiteThresholdPercent = float64(0.1)
+ inlineHotCallSiteThresholdPercent float64
+
+ // Threshold in CDF percentage for hot callsite inlining,
+ // that is, for a threshold of X the hottest callsites that
+ // make up the top X% of total edge weight will be
+ // considered hot for inlining candidates.
+ inlineCDFHotCallSiteThresholdPercent = float64(95)
// Budget increased due to hotness.
inlineHotMaxBudget int32 = 160
@@ -77,11 +84,12 @@ var (
// pgoInlinePrologue records the hot callsites from ir-graph.
func pgoInlinePrologue(p *pgo.Profile) {
- if s, err := strconv.ParseFloat(base.Debug.InlineHotCallSiteThreshold, 64); err == nil {
- inlineHotCallSiteThresholdPercent = s
- if base.Debug.PGOInline > 0 {
- fmt.Printf("hot-callsite-thres=%v\n", inlineHotCallSiteThresholdPercent)
- }
+ if s, err := strconv.ParseFloat(base.Debug.InlineHotCallSiteCDFThreshold, 64); err == nil {
+ inlineCDFHotCallSiteThresholdPercent = s
+ }
+ inlineHotCallSiteThresholdPercent = computeThresholdFromCDF(p)
+ if base.Debug.PGOInline > 0 {
+ fmt.Printf("hot-callsite-thres-from-CDF=%v\n", inlineHotCallSiteThresholdPercent)
}
if base.Debug.InlineHotBudget != 0 {
@@ -113,6 +121,38 @@ func pgoInlinePrologue(p *pgo.Profile) {
}
}
+func computeThresholdFromCDF(p *pgo.Profile) float64 {
+ nodes := make([]pgo.NodeMapKey, len(p.NodeMap))
+ i := 0
+ for n := range p.NodeMap {
+ nodes[i] = n
+ i++
+ }
+ sort.Slice(nodes, func(i, j int) bool {
+ ni, nj := nodes[i], nodes[j]
+ if wi, wj := p.NodeMap[ni].EWeight, p.NodeMap[nj].EWeight; wi != wj {
+ return wi > wj // want larger weight first
+ }
+ // same weight, order by name/line number
+ if ni.CallerName != nj.CallerName {
+ return ni.CallerName < nj.CallerName
+ }
+ if ni.CalleeName != nj.CalleeName {
+ return ni.CalleeName < nj.CalleeName
+ }
+ return ni.CallSite < nj.CallSite
+ })
+ cum := int64(0)
+ for _, n := range nodes {
+ w := p.NodeMap[n].EWeight
+ cum += w
+ if pgo.WeightInPercentage(cum, p.TotalEdgeWeight) > inlineCDFHotCallSiteThresholdPercent {
+ return pgo.WeightInPercentage(w, p.TotalEdgeWeight)
+ }
+ }
+ return 100
+}
+
// pgoInlineEpilogue updates IRGraph after inlining.
func pgoInlineEpilogue(p *pgo.Profile) {
if base.Debug.PGOInline > 0 {