Skip to content

Commit

Permalink
rename tags and update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nolanmar511 committed May 2, 2018
1 parent 23b71e4 commit 7788dda
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 36 deletions.
36 changes: 30 additions & 6 deletions doc/pprof.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,36 @@ search for them in a directory pointed to by the environment variable
* **-weblist= _regex_:** Generates a source/assembly combined annotated listing for
functions matching *regex*, and starts a web browser to display it.

## Comparing profiles

pprof can subtract one profile's samples from another in order to compare them.
For that, use the **-diff_base= _profile_** option, where *profile* is the filename
or URL for the profile to be subtracted (referred to as the base profile). When
using this mode, percentages reported in the output will be relative to the
total of the base profile. To separate samples that are part of the diff base
profile from those in the source profile, a string tag, "base"="1" is added to
all samples in the base profile. This means that if one saves the merged profile
and looks at it again with pprof, it will still be treated as a profile with a
diff base. It also means that any other samples which also have this tag will
be treated as part of the diff base profile.

If one is interested in the relative differences between the source and base
profiles (for example, which profile has a larger percentage of CPU time used
in a particular function), it can be useful to use the **-normalize** option.
With this option, the source profile is scaled so that the total of samples in
the source profile is equal to the total of samples in the base profile prior
to merging the profiles.

When comparing two cumulative profiles, for example two contention profiles
collected from the same program at different times, use the **-base** flag
in place of the **-diff_base** flag. When this flag is used and no negative
values appear in the merged profile when aggregated at the address-level,
which would be the case when comparing cummulative profiles collected from the
same program, percentages reported will be relative to the the difference
between the total for the source profile and the total for the base profile.
In the general case, percentages will be relative to the total of the absolute
value of all samples when aggregated at the address level.

# Fetching profiles

pprof can read profiles from a file or directly from a URL over http. Its native
Expand All @@ -235,11 +265,6 @@ them. This is useful to combine profiles from multiple processes of a
distributed job. The profiles may be from different programs but must be
compatible (for example, CPU profiles cannot be combined with heap profiles).

pprof can subtract a profile from another in order to compare them. For that,
use the **-base= _profile_** option, where *profile* is the filename or URL for the
profile to be subtracted. This may result on some report entries having negative
values.

## Symbolization

pprof can add symbol information to a profile that was collected only with
Expand Down Expand Up @@ -284,4 +309,3 @@ the symbolization handler.

* **-symbolize=demangle=templates:** Demangle, and trim function parameters, but
not template parameters.

16 changes: 8 additions & 8 deletions internal/driver/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) {
flag := o.Flagset
// Comparisons.
flagBase := flag.StringList("base", "", "Source for base profile for profile subtraction")
flagDiff := flag.StringList("diff", "", "Source for base profile for comparison")
flagDiffBase := flag.StringList("diff_base", "", "Source for diff base profile for comparison")
// Source options.
flagSymbolize := flag.String("symbolize", "", "Options for profile symbolization")
flagBuildID := flag.String("buildid", "", "Override build id for first mapping")
Expand Down Expand Up @@ -149,20 +149,20 @@ func parseFlags(o *plugin.Options) (*source, []string, error) {
}
}

var diff []string
for _, s := range *flagDiff {
var diffBase []string
for _, s := range *flagDiffBase {
if *s != "" {
diff = append(diff, *s)
diffBase = append(diffBase, *s)
}
}

if len(base) > 0 && len(diff) > 0 {
return nil, nil, fmt.Errorf("-base and -diff flags cannot both be specified")
if len(base) > 0 && len(diffBase) > 0 {
return nil, nil, fmt.Errorf("-base and -diff_base flags cannot both be specified")
}

source.Base = base
if len(diff) > 0 {
source.Base = diff
if len(diffBase) > 0 {
source.Base = diffBase
source.DiffBase = true
}

Expand Down
2 changes: 1 addition & 1 deletion internal/driver/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func grabSourcesAndBases(sources, bases []profileSource, isDiffBase bool, fetch
defer wg.Done()
pbase, mbase, savebase, countbase, errbase = chunkedGrab(bases, fetch, obj, ui)
if pbase != nil && isDiffBase {
pbase.SetTag("pprof::diff", []string{"true"})
pbase.SetTag("base", []string{"1"})
}
}()
wg.Wait()
Expand Down
20 changes: 10 additions & 10 deletions internal/driver/fetch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,39 +398,39 @@ func TestFetchWithBase(t *testing.T) {
},
{
values: []int64{-2700, -608881724},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
{
values: []int64{-100, -23992},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
{
values: []int64{-200, -179943},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
{
values: []int64{-100, -17778444},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
{
values: []int64{-100, -75976},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
{
values: []int64{-300, -63568134},
labels: map[string][]string{"pprof::diff": {"true"}},
labels: map[string][]string{"base": {"1"}},
},
},
"",
},
{
"diff and base both specified",
"diff_base and base both specified",
[]string{path + "cppbench.contention"},
[]string{path + "cppbench.contention"},
[]string{path + "cppbench.contention"},
false,
[]WantSample{},
"-base and -diff flags cannot both be specified",
"-base and -diff_base flags cannot both be specified",
},
}

Expand All @@ -450,8 +450,8 @@ func TestFetchWithBase(t *testing.T) {

f := testFlags{
stringLists: map[string][]*string{
"base": base,
"diff": diffBase,
"base": base,
"diff_base": diffBase,
},
bools: map[string]bool{
"normalize": tc.normalize,
Expand Down
6 changes: 3 additions & 3 deletions internal/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func (rpt *Report) newGraph(nodes graph.NodeSet) *graph.Graph {

// Remove tag marking samples from the base profiles, so it does not appear
// as a nodelet in the graph view.
prof.SetTag("pprof::diff", []string{})
prof.SetTag("base", []string{})

formatTag := func(v int64, key string) string {
return measurement.ScaledLabel(v, key, o.OutputUnit)
Expand Down Expand Up @@ -1216,7 +1216,7 @@ func NewDefault(prof *profile.Profile, options Options) *Report {
}

// computeTotal computes the sum of the absolute value of all sample values.
// If any samples have the tag "pprof::diff" with value "true", then the total
// If any samples have the tag "base" with value "1", then the total
// will only include samples with that tag.
func computeTotal(prof *profile.Profile, value, meanDiv func(v []int64) int64) int64 {
var div, total, diffDiv, diffTotal int64
Expand All @@ -1230,7 +1230,7 @@ func computeTotal(prof *profile.Profile, value, meanDiv func(v []int64) int64) i
v = -v
}
total += v
if sample.HasTag("pprof::diff", "true") {
if sample.HasTag("base", "1") {
diffTotal += v
diffDiv += d
}
Expand Down
16 changes: 8 additions & 8 deletions internal/report/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func TestComputeTotal(t *testing.T) {
{
Location: []*profile.Location{testL[2], testL[1], testL[0]},
Value: []int64{-10, 3},
Label: map[string][]string{"pprof::diff": {"true"}},
Label: map[string][]string{"base": {"1"}},
},
{
Location: []*profile.Location{testL[2], testL[1], testL[0]},
Expand All @@ -337,12 +337,12 @@ func TestComputeTotal(t *testing.T) {
{
Location: []*profile.Location{testL[2], testL[1], testL[0]},
Value: []int64{-9000, 3},
Label: map[string][]string{"pprof::diff": {"true"}},
Label: map[string][]string{"base": {"1"}},
},
{
Location: []*profile.Location{testL[2], testL[1], testL[0]},
Value: []int64{-1, 3},
Label: map[string][]string{"pprof::diff": {"true"}},
Label: map[string][]string{"base": {"1"}},
},
{
Location: []*profile.Location{testL[4], testL[2], testL[0]},
Expand All @@ -351,7 +351,7 @@ func TestComputeTotal(t *testing.T) {
{
Location: []*profile.Location{testL[2], testL[1], testL[0]},
Value: []int64{100, 3},
Label: map[string][]string{"pprof::diff": {"true"}},
Label: map[string][]string{"base": {"1"}},
},
}

Expand All @@ -362,31 +362,31 @@ func TestComputeTotal(t *testing.T) {
wantTotal int64
}{
{
desc: "non-diff profile, all positive values, index 1",
desc: "no diff base, all positive values, index 1",
prof: p1,
value: func(v []int64) int64 {
return v[0]
},
wantTotal: 3,
},
{
desc: "non-diff profile, all positive values, index 2",
desc: "no diff base, all positive values, index 2",
prof: p1,
value: func(v []int64) int64 {
return v[1]
},
wantTotal: 111,
},
{
desc: "non-diff profile, some negative values",
desc: "no diff base, some negative values",
prof: p2,
value: func(v []int64) int64 {
return v[1]
},
wantTotal: 111,
},
{
desc: "diff profile, some negative values",
desc: "diff base, some negative values",
prof: p3,
value: func(v []int64) int64 {
return v[0]
Expand Down

0 comments on commit 7788dda

Please sign in to comment.