Index: test/scale/driver.go |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/test/scale/driver.go |
@@ -0,0 +1,133 @@ |
+// Copyright 2011 The Go Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style |
+// license that can be found in the LICENSE file. |
+ |
+package main |
+ |
+import ( |
+ "fmt" |
+ "os" |
+ "flag" |
+ "time" |
+ "regexp" |
+ "runtime" |
+ "container/vector" |
+) |
+ |
+var flagBenchRun *string = flag.String("bench.run", "", "regular expression to select benchmarks to execute (all by default)") |
+var flagBenchProcs *int = flag.Int("bench.procs", 0, "number of processors (mandatory) (negative value means testing only on that number of processors)") |
+var flagBenchOut *string = flag.String("bench.out", "", "output filename (mandatory)") |
+var flagBenchTime *float64 = flag.Float64("bench.time", 1, "benchmarking time in seconds") |
+ |
+var benchmarking bool |
+var totalWork uint64 |
+ |
+type Benchmark struct { |
+ name string |
+ body func() |
+} |
+ |
+func output(file *os.File, str string) { |
+ fmt.Print(str) |
+ fmt.Fprint(file, str) |
+} |
+ |
+func warmup() { |
+ os.Setenv("GOGC", "1000") |
+ foo := make([]int8, 64*1024*1024) |
+ foo[0] = 0 |
+ procs := *flagBenchProcs |
+ if procs < 0 { |
+ procs = -procs |
+ } |
+ runtime.GOMAXPROCS(procs) |
+ compl := make(chan int, procs) |
+ for i := 0; i != procs; i += 1 { |
+ go func() { |
+ compl <- 0 |
+ }() |
+ } |
+ for i := 0; i != procs; i += 1 { |
+ <-compl |
+ } |
+} |
+ |
+func benchmarkImpl(outfile *os.File, benchmarks *vector.Vector) { |
+ for si := 0; si != benchmarks.Len(); si += 1 { |
+ b := benchmarks.At(si).(*Benchmark) |
+ if match, _ := regexp.MatchString(*flagBenchRun, b.name); !match { |
+ continue |
+ } |
+ output(outfile, fmt.Sprintf("%-24s", b.name)) |
+ pstart := 1 |
+ pend := *flagBenchProcs |
+ if *flagBenchProcs < 0 { |
+ pstart = -*flagBenchProcs |
+ pend = -*flagBenchProcs |
+ } |
+ for p := pstart; p <= pend; p += 1 { |
+ runtime.GOMAXPROCS(p) |
+ runtime.GC() |
+ benchmarking = true |
+ totalWork = 0 |
+ compl := make(chan int, 1) |
+ go func() { |
+ time.Sleep(int64(*flagBenchTime * 1e9)) |
+ benchmarking = false |
+ compl <- 0 |
+ }() |
+ startTime := time.Nanoseconds() |
+ b.body() |
+ execTime := uint64(time.Nanoseconds() - startTime) |
+ <-compl |
+ totalWork = totalWork * 1e6 / execTime |
+ output(outfile, fmt.Sprintf(" %-10d", totalWork)) |
+ for i := 0; runtime.Goroutines() > 2 && i != 10; i += 1 { |
+ time.Sleep(1e6) |
+ } |
+ if runtime.Goroutines() > 2 { |
+ panic("Some goroutines stay alive after the test") |
+ } |
+ time.Sleep(1e7) |
+ } |
+ output(outfile, "\n") |
+ } |
+} |
+ |
+func doBenchmark() { |
+ if *flagBenchProcs == 0 || *flagBenchOut == "" { |
+ flag.Usage() |
+ os.Exit(1) |
+ } |
+ |
+ outfile, err := os.OpenFile(*flagBenchOut, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) |
+ if outfile == nil { |
+ fmt.Printf("%s\n", err.String()) |
+ os.Exit(1) |
+ } |
+ defer outfile.Close() |
+ |
+ var benchmarks vector.Vector |
+ SuiteGoroutine(&benchmarks) |
+ SuiteSem(&benchmarks) |
+ SuiteOnce(&benchmarks) |
+ SuiteMutex(&benchmarks) |
+ SuiteRWMutex(&benchmarks) |
+ SuiteCondvar(&benchmarks) |
+ SuiteWaitGroup(&benchmarks) |
+ SuiteMatmult(&benchmarks) |
+ SuiteChan(&benchmarks) |
+ SuitePingPong(&benchmarks) |
+ |
+ benchmarkImpl(outfile, &benchmarks) |
+} |
+ |
+func main() { |
+ warmup() |
+ flag.Parse() |
+ if *flagDrawFile == "" { |
+ doBenchmark() |
+ } else { |
+ doDraw() |
+ } |
+} |