From: Austin Clements
Date: Thu, 17 Aug 2017 22:11:01 +0000 (-0400)
Subject: cmd/trace: display p99.9, p99 and p95 MUT
X-Git-Tag: go1.12beta1~487
X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b251d7fbe6d69e1ce81baf7959062ae489858f31;p=gostls13.git
cmd/trace: display p99.9, p99 and p95 MUT
This uses the mutator utilization distribution to compute the p99.9,
p99, and p95 mutator utilization topograph lines and display them
along with the MMU.
Change-Id: I8c7e0ec326aa4bc00619ec7562854253f01cc802
Reviewed-on: https://go-review.googlesource.com/c/60800
Run-TryBot: Austin Clements
TryBot-Result: Gobot Gobot
Reviewed-by: Hyang-Ah Hana Kim
---
diff --git a/src/cmd/trace/mmu.go b/src/cmd/trace/mmu.go
index 3fae3d6645..062e5ad2ca 100644
--- a/src/cmd/trace/mmu.go
+++ b/src/cmd/trace/mmu.go
@@ -88,6 +88,14 @@ func httpMMUPlot(w http.ResponseWriter, r *http.Request) {
return
}
+ var quantiles []float64
+ for _, flagStr := range strings.Split(r.FormValue("flags"), "|") {
+ if flagStr == "mut" {
+ quantiles = []float64{0, 1 - .999, 1 - .99, 1 - .95}
+ break
+ }
+ }
+
// Find a nice starting point for the plot.
xMin := time.Second
for xMin > 1 {
@@ -114,15 +122,21 @@ func httpMMUPlot(w http.ResponseWriter, r *http.Request) {
// Compute MMU curve.
logMin, logMax := math.Log(float64(xMin)), math.Log(float64(xMax))
const samples = 100
- plot := make([][2]float64, samples)
+ plot := make([][]float64, samples)
for i := 0; i < samples; i++ {
window := time.Duration(math.Exp(float64(i)/(samples-1)*(logMax-logMin) + logMin))
- y := mmuCurve.MMU(window)
- plot[i] = [2]float64{float64(window), y}
+ if quantiles == nil {
+ plot[i] = make([]float64, 2)
+ plot[i][1] = mmuCurve.MMU(window)
+ } else {
+ plot[i] = make([]float64, 1+len(quantiles))
+ copy(plot[i][1:], mmuCurve.MUD(window, quantiles))
+ }
+ plot[i][0] = float64(window)
}
// Create JSON response.
- err = json.NewEncoder(w).Encode(map[string]interface{}{"xMin": int64(xMin), "xMax": int64(xMax), "curve": plot})
+ err = json.NewEncoder(w).Encode(map[string]interface{}{"xMin": int64(xMin), "xMax": int64(xMax), "quantiles": quantiles, "curve": plot})
if err != nil {
log.Printf("failed to serialize response: %v", err)
return
@@ -150,6 +164,10 @@ var templMMU = `
else { return ns / 1e9 + 's'; }
}
+ function niceQuantile(q) {
+ return 'p' + q*100;
+ }
+
function mmuFlags() {
var flags = "";
$("#options input").each(function(i, elt) {
@@ -181,6 +199,11 @@ var templMMU = `
var data = new google.visualization.DataTable();
data.addColumn('number', 'Window duration');
data.addColumn('number', 'Minimum mutator utilization');
+ if (plotData.quantiles) {
+ for (var i = 1; i < plotData.quantiles.length; i++) {
+ data.addColumn('number', niceQuantile(1 - plotData.quantiles[i]) + ' MU');
+ }
+ }
data.addRows(curve);
for (var i = 0; i < curve.length; i++) {
data.setFormattedValue(i, 0, niceDuration(curve[i][0]));
@@ -201,6 +224,7 @@ var templMMU = `
maxValue: 1.0,
},
legend: { position: 'none' },
+ focusTarget: 'category',
width: 900,
height: 500,
chartArea: { width: '80%', height: '80%' },
@@ -208,6 +232,10 @@ var templMMU = `
for (var v = plotData.xMin; v <= plotData.xMax; v *= 10) {
options.hAxis.ticks.push({v:v, f:niceDuration(v)});
}
+ if (plotData.quantiles) {
+ options.vAxis.title = 'Mutator utilization';
+ options.legend.position = 'in';
+ }
var container = $('#mmu_chart');
container.empty();
@@ -298,6 +326,11 @@ var templMMU = `
?Sweep reclaims unused memory between GCs. (Enabling this may be very slow.).
+
+ Display
+
+ ?Display percentile mutator utilization in addition to minimum. E.g., p99 MU drops the worst 1% of windows.
+
Select a point for details.