aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHana Kim <hakim@google.com>2018-01-23 15:02:45 -0500
committerHyang-Ah Hana Kim <hyangah@gmail.com>2018-01-24 14:06:59 +0000
commite89d08e02180b72b541bcda0def3caf754704e25 (patch)
treedb7948deb8ce08c9efc77e095bf8ed7304916821
parent157d8cfbc13fbc4c849075e905b0001fb248b5e6 (diff)
downloadgo-e89d08e02180b72b541bcda0def3caf754704e25.tar.gz
go-e89d08e02180b72b541bcda0def3caf754704e25.zip
runtime/pprof: scale mutex profile with sampling rate
pprof expects the samples are scaled and reflects unsampled numbers. The legacy profile parser uses the sampling period in the output and multiplies all values with the period. https://github.com/google/pprof/blob/0138a3cd6dad6f94495ba0b5c3a5c124f04ae011/profile/legacy_profile.go#L815 Apply the same scaling when we output the mutex profile in the pprof proto format. Block profile shares the same code, but how to infer unsampled values is unclear. Legacy profile parser doesn't do anything special so we do nothing for block profile here. Tested by checking the profiles reported with debug=0 (proto format) are similar to the profiles computed from legacy format profile when the profile rate is a non-trivial number (e.g. 2) manually. Change-Id: Iaa33f92051deed67d8be43ddffc7c1016db566ca Reviewed-on: https://go-review.googlesource.com/89295 Reviewed-by: Peter Weinberger <pjw@google.com>
-rw-r--r--src/runtime/pprof/pprof.go25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
index d3382a5589..b7e5a1f92f 100644
--- a/src/runtime/pprof/pprof.go
+++ b/src/runtime/pprof/pprof.go
@@ -350,7 +350,8 @@ type countProfile interface {
// as the pprof-proto format output. Translations from cycle count to time duration
// are done because The proto expects count and time (nanoseconds) instead of count
// and the number of cycles for block, contention profiles.
-func printCountCycleProfile(w io.Writer, countName, cycleName string, records []runtime.BlockProfileRecord) error {
+// Possible 'scaler' functions are scaleBlockProfile and scaleMutexProfile.
+func printCountCycleProfile(w io.Writer, countName, cycleName string, scaler func(int64, float64) (int64, float64), records []runtime.BlockProfileRecord) error {
// Output profile in protobuf form.
b := newProfileBuilder(w)
b.pbValueType(tagProfile_PeriodType, countName, "count")
@@ -363,8 +364,9 @@ func printCountCycleProfile(w io.Writer, countName, cycleName string, records []
values := []int64{0, 0}
var locs []uint64
for _, r := range records {
- values[0] = int64(r.Count)
- values[1] = int64(float64(r.Cycles) / cpuGHz) // to nanoseconds
+ count, nanosec := scaler(r.Count, float64(r.Cycles)/cpuGHz)
+ values[0] = count
+ values[1] = int64(nanosec)
locs = locs[:0]
for _, addr := range r.Stack() {
// For count profiles, all stack addresses are
@@ -806,7 +808,7 @@ func writeBlock(w io.Writer, debug int) error {
sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
if debug <= 0 {
- return printCountCycleProfile(w, "contentions", "delay", p)
+ return printCountCycleProfile(w, "contentions", "delay", scaleBlockProfile, p)
}
b := bufio.NewWriter(w)
@@ -833,6 +835,14 @@ func writeBlock(w io.Writer, debug int) error {
return b.Flush()
}
+func scaleBlockProfile(cnt int64, ns float64) (int64, float64) {
+ // Do nothing.
+ // The current way of block profile sampling makes it
+ // hard to compute the unsampled number. The legacy block
+ // profile parse doesn't attempt to scale or unsample.
+ return cnt, ns
+}
+
// writeMutex writes the current mutex profile to w.
func writeMutex(w io.Writer, debug int) error {
// TODO(pjw): too much common code with writeBlock. FIX!
@@ -850,7 +860,7 @@ func writeMutex(w io.Writer, debug int) error {
sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
if debug <= 0 {
- return printCountCycleProfile(w, "contentions", "delay", p)
+ return printCountCycleProfile(w, "contentions", "delay", scaleMutexProfile, p)
}
b := bufio.NewWriter(w)
@@ -878,4 +888,9 @@ func writeMutex(w io.Writer, debug int) error {
return b.Flush()
}
+func scaleMutexProfile(cnt int64, ns float64) (int64, float64) {
+ period := runtime.SetMutexProfileFraction(-1)
+ return cnt * int64(period), ns * float64(period)
+}
+
func runtime_cyclesPerSecond() int64