[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC 14/59] benchmark: Store data in terms of worker sets and worker ids



From: George Dunlap <george.dunlap@xxxxxxxxxx>

...rather than having a single global index, in preparation for
summarizing sets of workers as well as individual workers.

To do this:

- Define a WorkerId type which consists of the worker set + worker id
  within that set.  Pass this to the workers and use this in the
  report values.

- Use maps based on this WorkerId for currently running processes,
  accumulated data, and (for now) the results summary.

In a future patch, we'll break down the results summary by worker sets
as well.

Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
 benchmark.go     | 120 +++++++++++++++++++++++++++----------------------------
 processworker.go |   4 +-
 xenworker.go     |   6 +--
 3 files changed, 63 insertions(+), 67 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 2a78d26..4354a47 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -33,8 +33,17 @@ type WorkerSummary struct {
        MinTput float64
 }
 
-type WorkerReport struct {
+type WorkerId struct {
+       Set int
        Id int
+}
+
+func (wid WorkerId) String() (string) {
+       return fmt.Sprintf("%d:%d", wid.Set, wid.Id)
+}
+
+type WorkerReport struct {
+       Id WorkerId
        Now int
        Mops int
        MaxDelta int
@@ -50,7 +59,7 @@ type WorkerSet struct {
 }
 
 type Worker interface {
-       SetId(int)
+       SetId(WorkerId)
        Init(WorkerParams) error
        Shutdown()
        Process(chan WorkerReport, chan bool)
@@ -86,13 +95,13 @@ func Report(ws *WorkerState, r WorkerReport) {
 
                tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)
                
-               fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+               fmt.Printf("%v Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
        }
 
        ws.LastReport = r
 }
 
-type WorkerList []WorkerState
+type WorkerList map[WorkerId]*WorkerState
 
 func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
        i = 0
@@ -114,41 +123,44 @@ const (
        WorkerXen = iota
 )
 
-func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
-       count := 0
+func NewWorkerList(workers []WorkerSet, workerType int) (wl WorkerList, err 
error) {
+       wl = WorkerList(make(map[WorkerId]*WorkerState))
 
-       // wsi: WorkerSet index
        for wsi := range workers {
-               count += workers[wsi].Count
-       }
+               for i := 0; i < workers[wsi].Count; i = i+1 {
+                       Id := WorkerId{Set:wsi,Id:i}
 
-       fmt.Println("Making ", count, " total workers")
-       ws = WorkerList(make([]WorkerState, count))
+                       ws := wl[Id]
 
-       // wli: WorkerList index
-       wli := 0
-       for wsi := range workers {
-               for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+                       if ws != nil {
+                               panic("Duplicate worker for id!")
+                       }
+                       
+                       ws = &WorkerState{}
+                       
                        switch workerType {
                        case WorkerProcess:
-                               ws[wli].w = &ProcessWorker{}
+                               ws.w = &ProcessWorker{}
                        case WorkerXen:
-                               ws[wli].w = &XenWorker{}
+                               ws.w = &XenWorker{}
                        default:
                                err = fmt.Errorf("Unknown type: %d", workerType)
+                               return
                        }
-                       ws[wli].w.SetId(wli)
+                       
+                       ws.w.SetId(Id)
                
-                       ws[wli].w.Init(workers[wsi].Params)
+                       ws.w.Init(workers[wsi].Params)
+
+                       wl[Id] = ws
                }
        }
        return
 }
 
 type BenchmarkRunData struct {
-       WorkerCount int
        Raw []WorkerReport       `json:",omitempty"`
-       Summary []WorkerSummary  `json:",omitempty"`
+       Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
@@ -174,8 +186,6 @@ func (run *BenchmarkRun) Run() (err error) {
        
        i := Workers.Start(report, done)
 
-       run.Results.WorkerCount = i
-
        // FIXME:
        // 1. Make a zero timeout mean "never"
        // 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
@@ -185,7 +195,7 @@ func (run *BenchmarkRun) Run() (err error) {
                select {
                case r := <-report:
                        run.Results.Raw = append(run.Results.Raw, r)
-                       Report(&Workers[r.Id], r)
+                       Report(Workers[r.Id], r)
                case <-done:
                        i--;
                        fmt.Println(i, "workers left");
@@ -215,22 +225,11 @@ func (run *BenchmarkRun) Run() (err error) {
 }
 
 func (run *BenchmarkRun) checkSummary() (done bool, err error) {
-       if run.Results.WorkerCount == 0 {
-               err = fmt.Errorf("Internal error: WorkerCount 0!")
-               return
-       }
-       
-       if len(run.Results.Summary) == run.Results.WorkerCount {
+       if run.Results.Summary != nil {
                done = true
                return 
        }
        
-       if len(run.Results.Summary) != 0 {
-               err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
-                       len(run.Results.Summary), run.Results.WorkerCount)
-               return
-       }
-
        return
 }
 
@@ -239,33 +238,31 @@ func (run *BenchmarkRun) Process() (err error) {
        if done || err != nil {
                return
        }
-       
-       wcount := run.Results.WorkerCount
-
-       if len(run.Results.Summary) != 0 {
-               err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
-                       len(run.Results.Summary), wcount)
-               return
-       }
 
-       run.Results.Summary = make([]WorkerSummary, wcount)
+       run.Results.Summary = make(map[WorkerId]*WorkerSummary)
 
-       // FIXME: Filter out results which started before all have started
-       
-       data := make([]struct{
+       type Data struct{
                startTime int
                lastTime int
-               lastMops int}, wcount)
+               lastMops int
+       }
+       
+       data := make(map[WorkerId]*Data)
 
+       // FIXME: Filter out results which started before all have started
        for i := range run.Results.Raw {
                e := run.Results.Raw[i]
-               if e.Id > wcount {
-                       err = fmt.Errorf("Internal error: id %d > wcount %d", 
e.Id, wcount)
-                       return
-               }
                
-               d := &data[e.Id]
-               s := &run.Results.Summary[e.Id]
+               d := data[e.Id]
+               if d == nil {
+                       d = &Data{}
+                       data[e.Id] = d
+               }
+               s := run.Results.Summary[e.Id]
+               if s == nil {
+                       s = &WorkerSummary{}
+                       run.Results.Summary[e.Id] = s
+               }
 
                if d.startTime == 0 {
                        d.startTime = e.Now
@@ -283,8 +280,9 @@ func (run *BenchmarkRun) Process() (err error) {
                d.lastMops = e.Mops
        }
 
-       for i := range data {
-               run.Results.Summary[i].AvgTput = Throughput(data[i].startTime, 
0, data[i].lastTime, data[i].lastMops)
+       for Id := range data {
+               run.Results.Summary[Id].AvgTput = Throughput(data[Id].startTime,
+                       0, data[Id].lastTime, data[Id].lastMops)
        }
        
        return
@@ -303,7 +301,6 @@ func (run *BenchmarkRun) TextReport() (err error) {
 
        fmt.Printf("== RUN %s ==", run.Label)
 
-       fmt.Printf(" Workers (%d total):\n", run.Results.WorkerCount)
        wStart := 0
        for i := range run.Workers {
                ws := &run.Workers[i]
@@ -317,10 +314,9 @@ func (run *BenchmarkRun) TextReport() (err error) {
        }
 
        fmt.Printf("\n%8s %8s %8s %8s\n", "id", "avg", "min", "max")
-       for i := 0; i < run.Results.WorkerCount; i++ {
-               s := &run.Results.Summary[i]
-               fmt.Printf("%8d %8.2f %8.2f %8.2f\n",
-                       i, s.AvgTput, s.MinTput, s.MaxTput)
+       for id, s := range run.Results.Summary {
+               fmt.Printf("%8v %8.2f %8.2f %8.2f\n",
+                       id, s.AvgTput, s.MinTput, s.MaxTput)
        }
 
        return
diff --git a/processworker.go b/processworker.go
index 6f70ce1..5e26d81 100644
--- a/processworker.go
+++ b/processworker.go
@@ -28,13 +28,13 @@ import (
 )
 
 type ProcessWorker struct {
-       id int
+       id WorkerId
        c *exec.Cmd
        stdout io.ReadCloser
        jsonStarted bool
 }
 
-func (w *ProcessWorker) SetId(i int) {
+func (w *ProcessWorker) SetId(i WorkerId) {
        w.id = i
 }
 
diff --git a/xenworker.go b/xenworker.go
index 7e85032..e14676c 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -28,7 +28,7 @@ import (
 )
 
 type XenWorker struct {
-       id int
+       id WorkerId
        vmname string
        domid int
        consoleCmd *exec.Cmd
@@ -52,9 +52,9 @@ type RumpRunConfig struct {
        Hostname string      `json:"hostname"`
 }
 
-func (w *XenWorker) SetId(i int) {
+func (w *XenWorker) SetId(i WorkerId) {
        w.id = i
-       w.vmname = fmt.Sprintf("worker-%d", i)
+       w.vmname = fmt.Sprintf("worker-%v", i)
        w.domid = -1 // INVALID DOMID
 }
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.