Esempio n. 1
0
// Save multiplot of histograms as SVG to file name.
// Construct a grid of histogram with the columns a test in the testsuite
// and a row per background load.
func writeStressHistograms(data []suite.StressResult, name, bgname string) {
	numLoads := len(data)
	numTests := len(data[0].Detail)

	maxRT := float64(-1)
	for i := range data {
		for _, rt := range data[i].Detail {
			for _, t := range rt {
				if float64(t) > maxRT {
					maxRT = float64(t)
				}
			}
		}
	}
	step := maxRT / 4
	maxRT, step = beautifulX(maxRT, step)

	tests := []string{}
	for t, _ := range data[0].Detail {
		tests = append(tests, t)
	}
	sort.Strings(tests)

	// A histogram
	now := time.Now()
	filename := outputPath + "stresstest_" + now.Format("2006-01-02_15-04-05") + ".svg"
	file, err := os.Create(filename)
	if err != nil {
		errorf("Cannot write to %q: %s", filename, err.Error())
		return
	}
	thesvg := svg.New(file)

	width, height := svgLeft+svgWidth*numTests, svgTop+svgHeight*numLoads+20
	thesvg.Start(width, height)
	thesvg.Title("Response Times")
	thesvg.Rect(0, 0, width, height, "fill: #ffffff")
	title := fmt.Sprintf("Distribution of response times in ms (suite: %s; bg: %s; %d samples; finished: %s)",
		name, bgname, len(data[0].Detail[tests[0]]), now.Format("Mon 2. Jan. 2006 15:04:05"))
	thesvg.Text(20, svgTop/2, title, "",
		"text-anchor: begin; font-size: 20;")

	for k, name := range tests {
		thesvg.Text(20+svgLeft+k*svgWidth, svgTop-2, name, "",
			"text-anchor: begin; font-size: 14;")
	}

	white := color.RGBA{255, 255, 255, 255}
	for i := range data {
		thesvg.Text(svgLeft-10, svgTop+svgHeight*i+0.5*svgHeight,
			fmt.Sprintf("%d || Req", data[i].Load+1), "",
			"text-anchor: end; font-size: 14;")
		for j, t := range tests {
			showTime, hd := false, 0
			if i == len(data)-1 {
				showTime = true
				hd += 20
			}
			thesvg.Gtransform(fmt.Sprintf("translate(%d %d)",
				svgLeft+svgWidth*j, svgTop+svgHeight*i))
			svggraphics := svgg.New(thesvg, svgWidth, svgHeight+hd, "Arial", 12, white)
			plotHistogram(svggraphics, data[i].Detail[t], maxRT, step, showTime)
			thesvg.Gend()
		}
	}
	thesvg.End()
	file.Close()
	warnf("Wrote stresstest histogram to file %s\n", filename)
}
Esempio n. 2
0
func InitStatsHUD() {
	plots := chart.ScatterChart{Title: "", Options: glchart.DarkStyle}
	start := time.Now()

	l := float64(start.UnixNano())
	r := float64(start.Add(2 * time.Second).UnixNano())

	plots.XRange.Fixed(l, r, 1e9)
	plots.YRange.Fixed(0.1, 100, 10)

	plots.XRange.TicSetting.Tics, plots.YRange.TicSetting.Tics = 1, 1
	plots.XRange.TicSetting.Mirror, plots.YRange.TicSetting.Mirror = 2, 2
	plots.XRange.TicSetting.Grid, plots.YRange.TicSetting.Grid = 2, 2

	plots.YRange.ShowZero = true

	//plots.XRange.Log = true
	//plots.YRange.Log = true

	plots.Key.Pos, plots.Key.Cols = "obc", 3

	plots.XRange.TicSetting.Format = func(f float64) string {
		t := time.Unix(int64(f)/1e9, int64(f)%1e9)
		return fmt.Sprintf("%.3v", time.Since(t))
	}

	memhelper.GetMaxRSS()

	var gpufree float64

	gpupoll := gpuinfo.PollGPUMemory()
	go func() {
		for gpustatus := range gpupoll {
			gpufree = float64(memhelper.ByteSize(gpustatus.Free()) * memhelper.MiB)
		}
	}()

	statistics := &Statistics{}
	statistics.Add(&plots, "GPU Free", "#FF9F00", func() float64 { return gpufree })
	statistics.Add(&plots, "SpareRAM()", "#ff0000", func() float64 { return float64(SpareRAM() * 1e6) })
	statistics.Add(&plots, "MaxRSS", "#FFE240", func() float64 { return float64(memhelper.GetMaxRSS()) })
	statistics.Add(&plots, "Heap Idle", "#33ff33", func() float64 { return float64(memstats.HeapIdle) })
	statistics.Add(&plots, "Alloc", "#FF6600", func() float64 { return float64(memstats.Alloc) })
	statistics.Add(&plots, "Heap Alloc", "#006699", func() float64 { return float64(memstats.HeapAlloc) })
	statistics.Add(&plots, "Sys", "#996699", func() float64 { return float64(memstats.Sys) })
	statistics.Add(&plots, "System Free", "#3333ff", func() float64 { return float64(SystemFree()) })
	statistics.Add(&plots, "nBlocks x 1e6", "#FFCC00", func() float64 { return float64(nblocks * 1e6) })
	statistics.Add(&plots, "nDrawn x 1e6", "#9C8AA5", func() float64 { return float64(blocks_rendered * 1e6) })

	go func() {
		top := 0.

		i := -1
		for {
			time.Sleep(250 * time.Millisecond)
			max := statistics.Update()
			if max > top {
				top = max
			}
			i++
			if i%4 != 0 {
				continue
			}

			segment := float64(1e9)
			if time.Since(start) > 10*time.Second {
				segment = 5e9
			}
			if time.Since(start) > 1*time.Minute {
				segment = 30e9
			}

			// Update axis limits
			nr := float64(time.Now().Add(2 * time.Second).UnixNano())
			plots.XRange.Fixed(l, nr, segment)
			plots.YRange.Fixed(-1e9, top*1.1, 500e6)
		}
	}()

	const pw, ph = 640, 480

	scalex, scaley := 0.4, 0.5

	chart_gfxcontext := glchart.New(pw, ph, "", 10, color.RGBA{})

	StatsHUD = func() {
		glh.With(glh.Matrix{gl.PROJECTION}, func() {
			gl.LoadIdentity()
			gl.Translated(1-scalex, scaley-1, 0)
			gl.Scaled(scalex, scaley, 1)
			gl.Ortho(0, pw, ph, 0, -1, 1)
			gl.Translated(0, -50, 0)

			glh.With(glh.Attrib{gl.ENABLE_BIT}, func() {
				gl.Disable(gl.DEPTH_TEST)
				glh.With(&Timer{Name: "Chart"}, func() {
					plots.Plot(chart_gfxcontext)
				})
			})
		})
	}

	// TODO: figure out why this is broken
	DumpStatsHUD = func() {
		s2f, _ := os.Create("statshud-dump.svg")
		mysvg := svg.New(s2f)
		mysvg.Start(1600, 800)
		mysvg.Rect(0, 0, 2000, 800, "fill: #ffffff")
		sgr := svgg.New(mysvg, 2000, 800, "Arial", 18,
			color.RGBA{0xff, 0xff, 0xff, 0xff})
		sgr.Begin()

		plots.Plot(sgr)

		sgr.End()
		mysvg.End()
		s2f.Close()
		log.Print("Saved statshud-dump.svg")
	}

	//log.Print("InitStatsHUD()")
}