1
0
mirror of https://github.com/golang/go synced 2024-11-17 09:54:46 -07:00

cmd/compile/internal/pgo: remove label handling

We don't use it. Make graph building a little faster.

Change-Id: I4a6f516f8e68bf338be8350f91c51f6f1dea26bc
Reviewed-on: https://go-review.googlesource.com/c/go/+/447800
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2022-11-03 19:46:57 -04:00
parent b725622ceb
commit 1a4cc091a9

View File

@ -23,12 +23,9 @@ import (
"math"
"path/filepath"
"sort"
"strconv"
"strings"
)
const maxNodelets = 4 // Number of nodelets for labels (both numeric and non)
// Options encodes the options for constructing a graph
type Options struct {
SampleValue func(s []int64) int64 // Function to compute the value of a sample
@ -66,15 +63,6 @@ type Node struct {
// In and out Contains the nodes immediately reaching or reached by
// this node.
In, Out EdgeMap
// LabelTags provide additional information about subsets of a sample.
LabelTags TagMap
// NumericTags provide additional values for subsets of a sample.
// Numeric tags are optionally associated to a label tag. The key
// for NumericTags is the name of the LabelTag they are associated
// to, or "" for numeric tags not associated to a label tag.
NumericTags map[string]TagMap
}
// Graph summarizes a performance profile into a format that is
@ -207,11 +195,9 @@ func (nm NodeMap) FindOrInsertNode(info NodeInfo, kept NodeSet) *Node {
}
n := &Node{
Info: info,
In: make(EdgeMap),
Out: make(EdgeMap),
LabelTags: make(TagMap),
NumericTags: make(map[string]TagMap),
Info: info,
In: make(EdgeMap),
Out: make(EdgeMap),
}
nm[info] = n
if info.Address == 0 && info.Lineno == 0 {
@ -252,43 +238,6 @@ func (e *Edge) WeightValue() int64 {
return e.Weight / e.WeightDiv
}
// Tag represent sample annotations
type Tag struct {
Name string
Unit string // Describe the value, "" for non-numeric tags
Value int64
Flat, FlatDiv int64
Cum, CumDiv int64
}
// FlatValue returns the exclusive value for this tag, computing the
// mean if a divisor is available.
func (t *Tag) FlatValue() int64 {
if t.FlatDiv == 0 {
return t.Flat
}
return t.Flat / t.FlatDiv
}
// CumValue returns the inclusive value for this tag, computing the
// mean if a divisor is available.
func (t *Tag) CumValue() int64 {
if t.CumDiv == 0 {
return t.Cum
}
return t.Cum / t.CumDiv
}
// TagMap is a collection of tags, classified by their name.
type TagMap map[string]*Tag
// SortTags sorts a slice of tags based on their weight.
func SortTags(t []*Tag, flat bool) []*Tag {
ts := tags{t, flat}
sort.Sort(ts)
return ts.t
}
// newGraph computes a graph from a profile. It returns the graph, and
// a map from the profile location indices to the corresponding graph
// nodes.
@ -315,7 +264,6 @@ func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) {
// A residual edge goes over one or more nodes that were not kept.
residual := false
labels := joinLabels(sample)
// Group the sample frames, based on a global map.
for i := len(sample.Location) - 1; i >= 0; i-- {
l := sample.Location[i]
@ -329,7 +277,7 @@ func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) {
// Add cum weight to all nodes in stack, avoiding double counting.
if _, ok := seenNode[n]; !ok {
seenNode[n] = true
n.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, false)
n.addSample(dw, w, false)
}
// Update edge weights for all edges in stack, avoiding double counting.
if _, ok := seenEdge[nodePair{n, parent}]; !ok && parent != nil && n != parent {
@ -342,7 +290,7 @@ func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) {
}
if parent != nil && !residual {
// Add flat weight to leaf node.
parent.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, true)
parent.addSample(dw, w, true)
}
}
@ -383,7 +331,6 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) {
continue
}
var parent *Node
labels := joinLabels(sample)
// Group the sample frames, based on a per-node map.
for i := len(sample.Location) - 1; i >= 0; i-- {
l := sample.Location[i]
@ -401,7 +348,7 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) {
if n == nil {
continue
}
n.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, false)
n.addSample(dw, w, false)
if parent != nil {
parent.AddToEdgeDiv(n, dw, w, false, lidx != len(lines)-1)
}
@ -409,7 +356,7 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) {
}
}
if parent != nil {
parent.addSample(dw, w, labels, sample.NumLabel, sample.NumUnit, o.FormatTag, true)
parent.addSample(dw, w, true)
}
}
@ -420,21 +367,6 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) {
return selectNodesForGraph(nodes, o.DropNegative)
}
func joinLabels(s *profile.Sample) string {
if len(s.Label) == 0 {
return ""
}
var labels []string
for key, vals := range s.Label {
for _, v := range vals {
labels = append(labels, key+":"+v)
}
}
sort.Strings(labels)
return strings.Join(labels, `\n`)
}
// isNegative returns true if the node is considered as "negative" for the
// purposes of drop_negative.
func isNegative(n *Node) bool {
@ -510,25 +442,6 @@ func nodeInfo(l *profile.Location, line profile.Line, objfile string, o *Options
return ni
}
type tags struct {
t []*Tag
flat bool
}
func (t tags) Len() int { return len(t.t) }
func (t tags) Swap(i, j int) { t.t[i], t.t[j] = t.t[j], t.t[i] }
func (t tags) Less(i, j int) bool {
if !t.flat {
if t.t[i].Cum != t.t[j].Cum {
return abs64(t.t[i].Cum) > abs64(t.t[j].Cum)
}
}
if t.t[i].Flat != t.t[j].Flat {
return abs64(t.t[i].Flat) > abs64(t.t[j].Flat)
}
return t.t[i].Name < t.t[j].Name
}
// Sum adds the flat and cum values of a set of nodes.
func (ns Nodes) Sum() (flat int64, cum int64) {
for _, n := range ns {
@ -538,7 +451,7 @@ func (ns Nodes) Sum() (flat int64, cum int64) {
return
}
func (n *Node) addSample(dw, w int64, labels string, numLabel map[string][]int64, numUnit map[string][]string, format func(int64, string) string, flat bool) {
func (n *Node) addSample(dw, w int64, flat bool) {
// Update sample value
if flat {
n.FlatDiv += dw
@ -547,63 +460,6 @@ func (n *Node) addSample(dw, w int64, labels string, numLabel map[string][]int64
n.CumDiv += dw
n.Cum += w
}
// Add string tags
if labels != "" {
t := n.LabelTags.findOrAddTag(labels, "", 0)
if flat {
t.FlatDiv += dw
t.Flat += w
} else {
t.CumDiv += dw
t.Cum += w
}
}
numericTags := n.NumericTags[labels]
if numericTags == nil {
numericTags = TagMap{}
n.NumericTags[labels] = numericTags
}
// Add numeric tags
if format == nil {
format = defaultLabelFormat
}
for k, nvals := range numLabel {
units := numUnit[k]
for i, v := range nvals {
var t *Tag
if len(units) > 0 {
t = numericTags.findOrAddTag(format(v, units[i]), units[i], v)
} else {
t = numericTags.findOrAddTag(format(v, k), k, v)
}
if flat {
t.FlatDiv += dw
t.Flat += w
} else {
t.CumDiv += dw
t.Cum += w
}
}
}
}
func defaultLabelFormat(v int64, key string) string {
return strconv.FormatInt(v, 10)
}
func (m TagMap) findOrAddTag(label, unit string, value int64) *Tag {
l := m[label]
if l == nil {
l = &Tag{
Name: label,
Unit: unit,
Value: value,
}
m[label] = l
}
return l
}
// String returns a text representation of a graph, for debugging purposes.
@ -670,28 +526,6 @@ func getNodesAboveCumCutoff(nodes Nodes, nodeCutoff int64) Nodes {
return cutoffNodes
}
// TrimLowFrequencyTags removes tags that have less than
// the specified weight.
func (g *Graph) TrimLowFrequencyTags(tagCutoff int64) {
// Remove nodes with value <= total*nodeFraction
for _, n := range g.Nodes {
n.LabelTags = trimLowFreqTags(n.LabelTags, tagCutoff)
for s, nt := range n.NumericTags {
n.NumericTags[s] = trimLowFreqTags(nt, tagCutoff)
}
}
}
func trimLowFreqTags(tags TagMap, minValue int64) TagMap {
kept := TagMap{}
for s, t := range tags {
if abs64(t.Flat) >= minValue || abs64(t.Cum) >= minValue {
kept[s] = t
}
}
return kept
}
// TrimLowFrequencyEdges removes edges that have less than
// the specified weight. Returns the number of edges removed
func (g *Graph) TrimLowFrequencyEdges(edgeCutoff int64) int {
@ -738,48 +572,12 @@ func (g *Graph) SelectTopNodes(maxNodes int, visualMode bool) NodeSet {
// selectTopNodes returns a slice of the top maxNodes nodes in a graph.
func (g *Graph) selectTopNodes(maxNodes int, visualMode bool) Nodes {
if maxNodes > 0 {
if visualMode {
var count int
// If generating a visual graph, count tags as nodes. Update
// maxNodes to account for them.
for i, n := range g.Nodes {
tags := countTags(n)
if tags > maxNodelets {
tags = maxNodelets
}
if count += tags + 1; count >= maxNodes {
maxNodes = i + 1
break
}
}
}
}
if maxNodes > len(g.Nodes) {
maxNodes = len(g.Nodes)
}
return g.Nodes[:maxNodes]
}
// countTags counts the tags with flat count. This underestimates the
// number of tags being displayed, but in practice is close enough.
func countTags(n *Node) int {
count := 0
for _, e := range n.LabelTags {
if e.Flat != 0 {
count++
}
}
for _, t := range n.NumericTags {
for _, e := range t {
if e.Flat != 0 {
count++
}
}
}
return count
}
// nodeSorter is a mechanism used to allow a report to be sorted
// in different ways.
type nodeSorter struct {