mirror of
https://github.com/golang/go
synced 2024-09-29 18:34:33 -06:00
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>
This commit is contained in:
parent
932330fdbf
commit
b07e845e76
@ -46,7 +46,7 @@ type DebugFlags struct {
|
||||
WB int `help:"print information about write barriers"`
|
||||
ABIWrap int `help:"print information about ABI wrapper generation"`
|
||||
MayMoreStack string `help:"call named function before all stack growth checks"`
|
||||
InlineHotCallSiteThreshold string `help:"threshold percentage for determining call sites as hot candidates for inlining"`
|
||||
InlineHotCallSiteCDFThreshold string `help:"cummulative threshold percentage for determining call sites as hot candidates for inlining"`
|
||||
InlineHotBudget int `help:"inline budget for hot functions"`
|
||||
PGOInline int `help:"debug profile-guided inlining"`
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user