blob: c769a7d52144879b585c510ed9a159375e63a160 [file] [log] [blame]
Jungho Ahnbc6ffa22014-12-10 17:55:35 -08001// A simple command-line tool to run IPC benchmarks.
2package main
3
4import (
5 "flag"
6 "fmt"
7 "os"
8 "runtime"
9 "strconv"
10 "strings"
11 "testing"
12
13 "veyron.io/veyron/veyron/lib/testutil"
14 "veyron.io/veyron/veyron/profiles"
15 "veyron.io/veyron/veyron/runtimes/google/ipc/benchmarks"
16
17 "veyron.io/veyron/veyron2"
18 "veyron.io/veyron/veyron2/rt"
19)
20
21var (
22 vrt veyron2.Runtime
23 address string
24
25 cpuList []int
26
27 histogram = flag.Bool("histogram", false, "If ture, output histogram of the benchmark results.")
28)
29
30func runBenchmarkEcho() {
31 payloadSizes := []int{1, 10, 100, 1000, 10000, 100000}
32
33 for _, size := range payloadSizes {
34 name := fmt.Sprintf("%sB", formatNum(size))
35 runBenchmark(name, func(b *testing.B, stats *testutil.BenchStats) {
36 benchmarks.CallEcho(b, vrt.NewContext(), address, b.N, size, stats)
37 })
38 }
39}
40
41func runBenchmarkEchoStream() {
42 chunkCnts := []int{1, 10, 100, 1000}
43 payloadSizes := []int{1, 10, 100, 1000, 10000, 100000}
44
45 for _, cnt := range chunkCnts {
46 for _, size := range payloadSizes {
47 name := formatNum(cnt)
48 if cnt == 1 {
49 name += "_chunk_"
50 } else {
51 name += "_chunks"
52 }
53 name += fmt.Sprintf("%sB", formatNum(size))
54 runBenchmark(name, func(b *testing.B, stats *testutil.BenchStats) {
55 benchmarks.CallEchoStream(b, vrt.NewContext(), address, b.N, cnt, size, stats)
56 })
57 }
58 }
59}
60
61func runBenchmarkEchoStreamPerChunk() {
62 payloadSizes := []int{1, 10, 100, 1000, 10000, 100000}
63
64 for _, size := range payloadSizes {
65 name := fmt.Sprintf("__per_chunk%sB", formatNum(size))
66 runBenchmark(name, func(b *testing.B, stats *testutil.BenchStats) {
67 benchmarks.CallEchoStream(b, vrt.NewContext(), address, 1, b.N, size, stats)
68 })
69 }
70}
71
72func runBenchmarkMux() {
73 payloadSizes := []int{10, 100}
74
75 chunkCntsB := []int{100, 1000}
76 payloadSizesB := []int{10, 100, 1000}
77
78 for _, size := range payloadSizes {
79 for _, cntB := range chunkCntsB {
80 for _, sizeB := range payloadSizesB {
81 name := fmt.Sprintf("%sB_mux%s", formatNum(size), formatNum(cntB))
82 if cntB == 1 {
83 name += "_chunk_"
84 } else {
85 name += "_chunks"
86 }
87 name += fmt.Sprintf("%sB", formatNum(sizeB))
88 runBenchmark(name, func(b *testing.B, stats *testutil.BenchStats) {
89 dummyB := testing.B{}
90 _, stop := benchmarks.StartEchoStream(&dummyB, vrt.NewContext(), address, 0, cntB, sizeB, nil)
91
92 b.ResetTimer()
93 benchmarks.CallEcho(b, vrt.NewContext(), address, b.N, size, stats)
94 b.StopTimer()
95
96 stop()
97 })
98 }
99 }
100 }
101}
102
103// runBenchmark runs a single bencmark function 'f'.
104func runBenchmark(name string, f func(*testing.B, *testutil.BenchStats)) {
105 for _, cpu := range cpuList {
106 runtime.GOMAXPROCS(cpu)
107
108 benchName := "Benchmark" + name
109 if cpu != 1 {
110 benchName += fmt.Sprintf("-%d", cpu)
111 }
112
113 var stats *testutil.BenchStats
114 if *histogram {
115 stats = testutil.NewBenchStats(16)
116 }
117
118 r := testing.Benchmark(func(b *testing.B) {
119 f(b, stats)
120 })
121
122 fmt.Printf("%s\t%s\n", benchName, r)
123 if stats != nil {
124 stats.Print(os.Stdout)
125 }
126 }
127}
128
129// formatNum formats the given number n with an optional metric prefix
130// and padding with underscores if necessary.
131func formatNum(n int) string {
132 value := float32(n)
133 var prefix string
134 for _, p := range []string{"", "K", "M", "G", "T"} {
135 if value < 1000 {
136 prefix = p
137 break
138 }
139 value /= 1000
140 }
141
142 return strings.Replace(fmt.Sprintf("%*.0f%s", 5-len(prefix), value, prefix), " ", "_", -1)
143}
144
145// parseCpuList looks up the existing '-test.cpu' flag value and parses it into
146// the list of cpus.
147func parseCpuList() {
148 for _, v := range strings.Split(flag.Lookup("test.cpu").Value.String(), ",") {
149 v = strings.TrimSpace(v)
150 if v == "" {
151 continue
152 }
153 cpu, err := strconv.Atoi(v)
154 if err != nil || cpu <= 0 {
155 fmt.Fprintf(os.Stderr, "invalid -test.cpu %q\n", v)
156 os.Exit(1)
157 }
158 cpuList = append(cpuList, cpu)
159 }
160 if cpuList == nil {
161 cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
162 }
163}
164
165func main() {
166 flag.Parse()
167 parseCpuList()
168
169 var err error
170 vrt, err = rt.New()
171 if err != nil {
172 panic(err)
173 }
174 defer vrt.Cleanup()
175
176 var stop func()
177 address, stop = benchmarks.StartServer(vrt, profiles.LocalListenSpec)
178
179 runBenchmarkEcho()
180 runBenchmarkEchoStream()
181 runBenchmarkEchoStreamPerChunk()
182 runBenchmarkMux()
183
184 stop()
185}