SCM Repository
Annotation of /benchmarks/analysis/speedup.sml
Parent Directory
|
Revision Log
Revision 3068 - (view) (download)
1 : | jhr | 3059 | (* speedup.sml |
2 : | * | ||
3 : | * COPYRIGHT (c) 2015 The Diderot Project (http://diderot-language.cs.uchicago.edu) | ||
4 : | * All rights reserved. | ||
5 : | * | ||
6 : | * Code to generate a speedup plot for the pthread parallel implementation. | ||
7 : | *) | ||
8 : | |||
9 : | jhr | 3068 | structure Speedup (*: sig |
10 : | jhr | 3059 | |
11 : | val gen : { | ||
12 : | (* data set to plot *) | ||
13 : | data : Benchmark.data, | ||
14 : | (* specification of benchmarks to plot, along with their styling info *) | ||
15 : | bmarks : { | ||
16 : | name : string, | ||
17 : | symbol : string, | ||
18 : | line : string | ||
19 : | } list, | ||
20 : | (* baseline benchmark: should be "teem", "seq", "par-1" (for 1-processor) *) | ||
21 : | baseline : string, | ||
22 : | (* output file *) | ||
23 : | output : string, | ||
24 : | (* should the perfect speedup line be drawn? *) | ||
25 : | perfect : bool | ||
26 : | jhr | 3065 | } -> OS.Process.status |
27 : | jhr | 3059 | |
28 : | jhr | 3068 | end*) = struct |
29 : | jhr | 3059 | |
30 : | structure B = Benchmark | ||
31 : | structure P = Ploticus | ||
32 : | structure F = Format | ||
33 : | structure A2 = Array2 | ||
34 : | |||
35 : | fun pr (outS, s) = TextIO.output(outS, s) | ||
36 : | fun prl (outS, items) = List.app (fn s => pr(outS, s)) items | ||
37 : | fun prf (outS, fmt, items) = pr(outS, Format.format fmt items) | ||
38 : | |||
39 : | jhr | 3065 | (* location of lower-left corner *) |
40 : | val llX = 1.0 | ||
41 : | val llY = 1.0 | ||
42 : | jhr | 3068 | (* |
43 : | val plotWid = 6.0 | ||
44 : | val plotHt = 6.0 | ||
45 : | fun dimensions (nProcs, maxY) = let | ||
46 : | val np = real nProcs | ||
47 : | val h = Real.max (np, realCeil maxY) | ||
48 : | val w = np+1.0 | ||
49 : | in | ||
50 : | end | ||
51 : | *) | ||
52 : | jhr | 3065 | |
53 : | jhr | 3059 | (* extract the data from a benchmark *) |
54 : | fun extractData (baseline, b : B.benchmark) = let | ||
55 : | fun isPar (r : B.results) = if String.isPrefix "par-" (#name r) | ||
56 : | then SOME(valOf(Int.fromString(String.extract(#name r, 4, NONE))), valOf(#avg_time r)) | ||
57 : | else NONE | ||
58 : | val data = List.mapPartial isPar (#results b) | ||
59 : | in | ||
60 : | case List.find (fn r => (baseline = #name r)) (#results b) | ||
61 : | of SOME r => (valOf(#avg_time r), data) | ||
62 : | | NONE => raise Fail "no baseline data" | ||
63 : | (* end case *) | ||
64 : | end | ||
65 : | |||
66 : | type bmark_info = { | ||
67 : | col : int, | ||
68 : | name : string, | ||
69 : | symbol : string, | ||
70 : | line : string, | ||
71 : | data : B.benchmark | ||
72 : | } | ||
73 : | |||
74 : | fun computeSpeedup (baseline, data : bmark_info list) = let | ||
75 : | (* determine the minimum max_nprocs value of the data *) | ||
76 : | val maxNProcs = List.foldl (fn ({data, ...}, n) => Int.min(n, #max_nprocs data)) 256 data | ||
77 : | (* allocate the data table *) | ||
78 : | val tbl = A2.array (maxNProcs, List.length data, 0.0) | ||
79 : | (* process a benchmark *) | ||
80 : | fun doBenchmark ({col, data, ...} : bmark_info) = let | ||
81 : | (* get performance data *) | ||
82 : | val (baseAvg, avgTimes) = extractData (baseline, data) | ||
83 : | jhr | 3065 | fun update (i, t) = A2.update(tbl, i-1, col, baseAvg / t) |
84 : | jhr | 3059 | in |
85 : | List.app update avgTimes | ||
86 : | end | ||
87 : | in | ||
88 : | List.app doBenchmark data; | ||
89 : | tbl | ||
90 : | end | ||
91 : | |||
92 : | jhr | 3065 | fun genData (outS, tbl) = let |
93 : | jhr | 3059 | val lastCol = A2.nCols tbl - 1 |
94 : | fun output (r, c, v) = ( | ||
95 : | if (c > 0) | ||
96 : | then prf(outS, " %5.2f", [F.REAL v]) | ||
97 : | jhr | 3065 | else prf(outS, " %2d %5.2f", [F.INT(r+1), F.REAL v]); |
98 : | jhr | 3059 | if (c = lastCol) |
99 : | then pr (outS, "\n") | ||
100 : | else ()) | ||
101 : | in | ||
102 : | pr (outS, "// speedup data\n"); | ||
103 : | pr (outS, "//\n"); | ||
104 : | pr (outS, "#proc getdata\n"); | ||
105 : | pr (outS, "data:\n"); | ||
106 : | A2.appi A2.RowMajor output {base=tbl, col=0, row=0, ncols=NONE, nrows=NONE}; | ||
107 : | pr (outS, "\n") | ||
108 : | end | ||
109 : | |||
110 : | jhr | 3065 | fun genAreaDef (outS, nprocs) = ( |
111 : | pr (outS, "#proc areadef\n"); | ||
112 : | jhr | 3068 | prf (outS, " rectangle: %5.2f %5.2f 5.0 5.5\n", [F.REAL llX, F.REAL llY]); |
113 : | jhr | 3065 | prf (outS, " xrange: 0.5 %d.5\n", [F.INT nprocs]); |
114 : | prf (outS, " yrange: 0 %d\n\n", [F.INT nprocs])) | ||
115 : | |||
116 : | fun genAxis (outS, axis, label, stubInc, stubMin, stubMax, location) = ( | ||
117 : | prf (outS, "#proc %s\n", [F.STR axis]); | ||
118 : | prf (outS, " label: %s\n", [F.STR label]); | ||
119 : | prf (outS, " stubs: inc %d\n", [F.INT stubInc]); | ||
120 : | prf (outS, " stubrange: %d %d\n", [F.INT stubMin, F.INT stubMax]); | ||
121 : | prf (outS, " location: %5.2f\n\n", [F.REAL location])) | ||
122 : | |||
123 : | fun genLinePlot (outS, xcol, ycol, symbol, line, label, sample) = let | ||
124 : | fun prOpt (_, "") = () | ||
125 : | | prOpt (cmd, opts) = prf(outS, " %s: %s\n", [F.STR cmd, F.STR opts]) | ||
126 : | in | ||
127 : | pr (outS, "#proc lineplot\n"); | ||
128 : | prf (outS, " xfield: %d\n", [F.INT xcol]); | ||
129 : | prf (outS, " yfield: %d\n", [F.INT ycol]); | ||
130 : | prOpt ("pointsymbol", symbol); | ||
131 : | prOpt ("linedetails", line); | ||
132 : | prOpt ("legendlabel", label); | ||
133 : | prOpt ("legendsampletype", sample); | ||
134 : | pr (outS, "\n") | ||
135 : | end | ||
136 : | |||
137 : | fun genBmarkPlot outS (info : bmark_info) = | ||
138 : | genLinePlot (outS, 1, #col info + 2, #symbol info, #line info, #name info, "line+symbol") | ||
139 : | |||
140 : | jhr | 3068 | fun genLegend (outS, x, y, title) = ( |
141 : | pr (outS, "#proc legend\n"); | ||
142 : | prf (outS, " location: %5.2f %5.2f\n", [F.REAL x, F.REAL y]); | ||
143 : | pr (outS, " nlinesym: 1\n"); | ||
144 : | pr (outS, " frame: yes\n"); | ||
145 : | pr (outS, " textdetails: align=left size=10\n"); | ||
146 : | if (title <> "") | ||
147 : | then ( | ||
148 : | prf (outS, " title: %s\n", [F.STR title]); | ||
149 : | pr (outS, " titledetails: style=b align=left size=12\n\n")) | ||
150 : | else pr (outS, "\n")) | ||
151 : | |||
152 : | fun gen {data=[], ...} = raise Fail "no data" | ||
153 : | | gen {data : B.data, bmarks, baseline, output, perfect} = let | ||
154 : | val {host, version, date, ...} = hd data | ||
155 : | jhr | 3059 | (* for each benchmark in the plot, find the data and pair it with the plotting |
156 : | * info. | ||
157 : | *) | ||
158 : | val data = let | ||
159 : | fun find (b as {name, symbol, line}) = ( | ||
160 : | case List.find (fn {bmark, ...} => (bmark = name)) data | ||
161 : | of NONE => raise Fail("no data for "^name) | ||
162 : | | SOME data => (b, data) | ||
163 : | (* end case *)) | ||
164 : | in | ||
165 : | List.map find bmarks | ||
166 : | end | ||
167 : | jhr | 3065 | (* assign columns in the data table to the benchmarks. These are 0-based, but the |
168 : | * actual first column is field 2 for Ploticus. | ||
169 : | jhr | 3059 | *) |
170 : | val data = let | ||
171 : | fun lp (_, []) = [] | ||
172 : | | lp (i, ({name, symbol, line}, data)::r) = let | ||
173 : | val r = lp (i+1, r) | ||
174 : | in | ||
175 : | {col = i, name = name, symbol = symbol, line = line, data = data} :: r | ||
176 : | end | ||
177 : | in | ||
178 : | lp (0, data) | ||
179 : | end | ||
180 : | jhr | 3065 | (* fill in the data table *) |
181 : | val tbl = computeSpeedup (baseline, data) | ||
182 : | jhr | 3068 | val args = P.output output @ P.toEPS @ P.timesRoman 10 |
183 : | jhr | 3065 | val nProcs = A2.nRows tbl |
184 : | (* generate the plot description to an output stream *) | ||
185 : | fun plot outS = ( | ||
186 : | genData (outS, tbl); | ||
187 : | genAreaDef (outS, nProcs); | ||
188 : | genAxis (outS, "xaxis", "Number of threads", 1, 1, nProcs, llY); | ||
189 : | genAxis (outS, "yaxis", "Speedup", 1, 0, nProcs, llX); | ||
190 : | if perfect | ||
191 : | then genLinePlot (outS, 1, 1, "", "style=1 color=red", "perfect speedup", "") | ||
192 : | else (); | ||
193 : | jhr | 3068 | List.app (genBmarkPlot outS) data; |
194 : | genLegend (outS, 2.0, 6.5, concat["Parallel speedup on ", host, "[", date, "]"])) | ||
195 : | jhr | 3059 | in |
196 : | jhr | 3065 | plot(TextIO.stdOut); |
197 : | P.run args plot | ||
198 : | jhr | 3059 | end |
199 : | |||
200 : | end | ||
201 : | |||
202 : |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |