mirror of
https://github.com/golang/go
synced 2024-11-19 15:34:47 -07:00
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.
0138a3cd6d/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>
This commit is contained in:
parent
157d8cfbc1
commit
e89d08e021
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user