diff options
| author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-02-20 12:05:00 -0500 |
|---|---|---|
| committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-02-20 12:05:00 -0500 |
| commit | edde9793da12398d11909a1be2041db93080d22a (patch) | |
| tree | ab64612ad8f44da3dcfb9097e50041172fd05074 | |
| parent | 5e5fc221d60f46951a360f3e4f637e0edc084daf (diff) | |
add support for plotting trendlines
| -rwxr-xr-x | oplot.py | 95 |
1 files changed, 87 insertions, 8 deletions
| @@ -75,6 +75,10 @@ TXT = { | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | 77 | ||
| 78 | HOST_CPUS = { | ||
| 79 | 'ludwig' : 24, | ||
| 80 | } | ||
| 81 | |||
| 78 | def get_stats_label(samples): | 82 | def get_stats_label(samples): |
| 79 | avg = numpy.mean(samples) | 83 | avg = numpy.mean(samples) |
| 80 | med = numpy.median(samples) | 84 | med = numpy.median(samples) |
| @@ -172,25 +176,34 @@ class OverheadPlotter(defapp.App): | |||
| 172 | 176 | ||
| 173 | p = self.make_plot(name) | 177 | p = self.make_plot(name) |
| 174 | 178 | ||
| 179 | samples_label = "samples: total=%d filtered=%d (%.2f%%)" % \ | ||
| 180 | (len(data), len(data) - len(samples), discarded) | ||
| 175 | 181 | ||
| 176 | iqr_label = "\\n".join(["samples: total=%d filtered=%d (%.2f%%)", | 182 | if self.options.extent: |
| 177 | "IQR: extent=%d threshold=%.2fus", | 183 | iqr_label = "IQR: extent=%d threshold=%.2fus" % \ |
| 178 | ]) % \ | 184 | (self.options.extent, iqr_max) |
| 179 | (len(data), len(data) - len(samples), discarded, | 185 | elif discarded > 0: |
| 180 | self.options.extent, iqr_max) | 186 | iqr_label = "manual threshold=1000us [IQR not applied]" |
| 187 | else: | ||
| 188 | iqr_label = "[IQR filter not applied]" | ||
| 189 | samples_label = "samples: total=%d" % len(data) | ||
| 190 | |||
| 191 | data_label = "%s\\n%s" % (samples_label, iqr_label) | ||
| 181 | 192 | ||
| 182 | p.labels = [label(0.5, 0.9, | 193 | p.labels = [label(0.5, 0.9, |
| 183 | get_stats_label(samples), | 194 | get_stats_label(samples), |
| 184 | coord=['graph', 'screen'], align='center'), | 195 | coord=['graph', 'screen'], align='center'), |
| 185 | label(0.98, 0.95, iqr_label, | 196 | label(0.98, 0.95, data_label, |
| 186 | coord=['graph', 'graph'], align='right')] | 197 | coord=['graph', 'graph'], align='right')] |
| 187 | 198 | ||
| 188 | (hist, fname, edges) = self.write_histogram(samples, name) | 199 | (hist, fname, edges) = self.write_histogram(samples, name) |
| 189 | 200 | ||
| 190 | p.setup_histogram(gap=1, boxwidth=1.0) | 201 | p.setup_histogram(gap=1, boxwidth=1.0) |
| 191 | 202 | ||
| 192 | p.title = "%s: measured %s for %s tasks per processor (host=%s)" \ | 203 | p.title = "%s: measured %s for %s task%s per processor (host=%s)" \ |
| 193 | % (conf['scheduler'], TXT[conf['overhead']], conf['n'], conf['host']) | 204 | % (conf['scheduler'], TXT[conf['overhead']], |
| 205 | conf['n'], 's' if conf['n'] != '1' else '', | ||
| 206 | conf['host']) | ||
| 194 | 207 | ||
| 195 | if self.options.normalize: | 208 | if self.options.normalize: |
| 196 | p.ylabel = "fraction of samples" | 209 | p.ylabel = "fraction of samples" |
| @@ -220,6 +233,71 @@ class OverheadPlotter(defapp.App): | |||
| 220 | 233 | ||
| 221 | self.render(p) | 234 | self.render(p) |
| 222 | 235 | ||
| 236 | def prepare_trends(self, datafile, name, conf): | ||
| 237 | data = load_csv_file(datafile) | ||
| 238 | if 'host' in conf and conf['host'] in HOST_CPUS: | ||
| 239 | cpus = HOST_CPUS[conf['host']] | ||
| 240 | if conf['scheduler'].endswith('-RM'): | ||
| 241 | cpus -= 1 | ||
| 242 | else: | ||
| 243 | cpus = 1 | ||
| 244 | # format | ||
| 245 | n_idx = 2 | ||
| 246 | wc_idx = 5 | ||
| 247 | avg_idx = 6 | ||
| 248 | std_idx = 9 | ||
| 249 | |||
| 250 | rows = [ [r[n_idx] * cpus, | ||
| 251 | r[wc_idx], | ||
| 252 | r[avg_idx], | ||
| 253 | r[std_idx]] | ||
| 254 | for r in data] | ||
| 255 | |||
| 256 | max_y = numpy.amax(data[:,wc_idx]) | ||
| 257 | |||
| 258 | return (self.write(rows, name), cpus, max_y) | ||
| 259 | |||
| 260 | def plot_trends(self, datafile, name, conf): | ||
| 261 | fname, cpus, max_y = self.prepare_trends(datafile, name, conf) | ||
| 262 | |||
| 263 | p = self.make_plot(name) | ||
| 264 | |||
| 265 | p.title = "measured %s under %s scheduling" \ | ||
| 266 | % (TXT[conf['overhead']], conf['scheduler']) | ||
| 267 | |||
| 268 | p.ylabel = "overhead in microseconds" | ||
| 269 | p.xlabel = "number of tasks" | ||
| 270 | |||
| 271 | if self.options.xmax: | ||
| 272 | p.xrange = (0, self.options.xmax) | ||
| 273 | else: | ||
| 274 | p.xrange = (0, ceil(cpus * 20 / 100.0) * 100) | ||
| 275 | |||
| 276 | if self.options.ymax: | ||
| 277 | p.yrange = (0, self.options.ymax) | ||
| 278 | else: | ||
| 279 | p.yrange = (0, (ceil(max_y / 50.0)) * 50) | ||
| 280 | |||
| 281 | p.xticks = (0, max(cpus, 10)) | ||
| 282 | p.curves = [curve(fname, xcol=1, ycol=2, title="maximum"), | ||
| 283 | curve(fname, xcol=1, ycol=3, style="lines", title='average'), | ||
| 284 | curve(fname, xcol=1, ycol=3, error=4, title="std. deviation")] | ||
| 285 | |||
| 286 | #### Styling. | ||
| 287 | |||
| 288 | if not self.setup_png(p): | ||
| 289 | p.rounded_caps = True | ||
| 290 | p.font = 'Helvetica' | ||
| 291 | |||
| 292 | p.font_size = '10' | ||
| 293 | p.size = ('20cm', '10cm') | ||
| 294 | p.monochrome = False | ||
| 295 | p.dashed_lines = False | ||
| 296 | p.key = 'left top' | ||
| 297 | p.default_style = 'linespoints lw 1' | ||
| 298 | |||
| 299 | self.render(p) | ||
| 300 | |||
| 223 | 301 | ||
| 224 | def plot_file(self, datafile): | 302 | def plot_file(self, datafile): |
| 225 | bname = basename(datafile) | 303 | bname = basename(datafile) |
| @@ -227,6 +305,7 @@ class OverheadPlotter(defapp.App): | |||
| 227 | conf = decode(name) | 305 | conf = decode(name) |
| 228 | plotters = { | 306 | plotters = { |
| 229 | 'taskset' : self.plot_samples, | 307 | 'taskset' : self.plot_samples, |
| 308 | 'otrend' : self.plot_trends, | ||
| 230 | } | 309 | } |
| 231 | 310 | ||
| 232 | for plot_type in plotters: | 311 | for plot_type in plotters: |
