diff options
Diffstat (limited to 'plot.py')
-rwxr-xr-x | plot.py | 138 |
1 files changed, 138 insertions, 0 deletions
@@ -0,0 +1,138 @@ | |||
1 | #!/usr/bin/env python | ||
2 | import defapp | ||
3 | from os.path import splitext, basename | ||
4 | from optparse import make_option as o | ||
5 | from tempfile import NamedTemporaryFile as Tmp | ||
6 | |||
7 | from gnuplot import gnuplot, FORMATS | ||
8 | |||
9 | options = [ | ||
10 | o('-f', '--format', action='store', dest='format', type='choice', | ||
11 | choices=FORMATS, help='output format'), | ||
12 | ] | ||
13 | |||
14 | defaults = { | ||
15 | 'format' : 'show', | ||
16 | 'xrange' : (0.5, 32.5), | ||
17 | 'yrange' : (-0.05, 1.05), | ||
18 | 'xticks' : (0, 2), | ||
19 | 'yticks' : (0, 0.1), | ||
20 | 'title' : None, | ||
21 | 'xlabel' : 'task set utilization cap (prior to inflation)', | ||
22 | 'ylabel' : 'ratio of schedulable task sets', | ||
23 | } | ||
24 | |||
25 | def decode(name): | ||
26 | params = {} | ||
27 | parts = name.split('_') | ||
28 | for p in parts: | ||
29 | kv = p.split('=') | ||
30 | k = kv[0] | ||
31 | v = kv[1] if len(kv) > 1 else None | ||
32 | params[k] = v | ||
33 | return params | ||
34 | |||
35 | def get_data_tmpfile(datafile): | ||
36 | """Removes all comments form datafile, stores result in a temp file. | ||
37 | The temp file is returned.""" | ||
38 | count = 0 | ||
39 | f = open(datafile, 'r') | ||
40 | d = Tmp() | ||
41 | for line in f: | ||
42 | if len(line) > 1 and line[0] != '#': | ||
43 | d.write(line) | ||
44 | count += 1 | ||
45 | f.close() | ||
46 | d.flush() | ||
47 | if count > 0: | ||
48 | return d | ||
49 | else: | ||
50 | del d # removes temp file | ||
51 | return None | ||
52 | |||
53 | def scenario_heading(conf): | ||
54 | dist = 'unknown distribution' | ||
55 | if 'dist' in conf: | ||
56 | if conf['dist'] == 'uni': | ||
57 | dist = 'uniformly distributed' | ||
58 | if 'light' in conf: | ||
59 | dist = dist + ' in [0.001, 0.1]' | ||
60 | elif 'medium' in conf: | ||
61 | dist = dist + ' in [0.1, 0.4]' | ||
62 | elif 'heavy' in conf: | ||
63 | dist = dist + ' in [0.5, 0.9]' | ||
64 | elif conf['dist'] == 'bimo': | ||
65 | dist = 'bimodially distributed' | ||
66 | if 'light' in conf: | ||
67 | dist = dist + 'in [0.001, 0.5] (8/9) and [0.5, 0.9] (1/9)' | ||
68 | elif 'medium' in conf: | ||
69 | dist = dist + 'in [0.001, 0.5] (6/9) and [0.5, 0.9] (3/9)' | ||
70 | elif 'heavy' in conf: | ||
71 | dist = dist + 'in [0.001, 0.5] (4/9) and [0.5, 0.9] (5/9)' | ||
72 | return dist | ||
73 | |||
74 | class SchedPlotter(defapp.App): | ||
75 | def __init__(self): | ||
76 | defapp.App.__init__(self, options, defaults, no_std_opts=True) | ||
77 | |||
78 | def plot(self, graphs, title, name, conf): | ||
79 | gnuplot(graphs, title=title, | ||
80 | xlabel=self.options.xlabel, | ||
81 | ylabel=self.options.ylabel + | ||
82 | (' [soft]' if 'soft' in conf else ' [hard]'), | ||
83 | xrange=self.options.xrange, | ||
84 | yrange=self.options.yrange, | ||
85 | xticks=self.options.xticks, | ||
86 | yticks=self.options.yticks, | ||
87 | format=self.options.format, | ||
88 | fname=name) | ||
89 | |||
90 | def plot_spec(self, tmpfile, name, conf): | ||
91 | title = 'release overhead speculation: ' + scenario_heading(conf) | ||
92 | graphs = [ | ||
93 | (tmpfile, 1, 2, 'G-EDF (100% release)'), | ||
94 | (tmpfile, 1, 3, 'G-EDF ( 75% release)'), | ||
95 | (tmpfile, 1, 4, 'G-EDF ( 50% release)'), | ||
96 | (tmpfile, 1, 5, 'G-EDF ( 25% release)'), | ||
97 | (tmpfile, 1, 6, 'G-EDF ( 0% release)'), | ||
98 | (tmpfile, 1, 7, 'G-EDF (no overheads)'), | ||
99 | ] | ||
100 | self.plot(graphs, title, name, conf) | ||
101 | |||
102 | def plot_spec2(self, tmpfile, name, conf): | ||
103 | title = 'service processor speculation: ' + scenario_heading(conf) | ||
104 | graphs = [ | ||
105 | (tmpfile, 1, 2, 'G-EDF ( 25% release, 100% rest)'), | ||
106 | (tmpfile, 1, 3, 'G-EDF (100% release, 0% rest)'), | ||
107 | (tmpfile, 1, 4, 'G-EDF (service cpu, 100% preempt)'), | ||
108 | (tmpfile, 1, 5, 'G-EDF (service cpu, 150% preempt)'), | ||
109 | ] | ||
110 | self.plot(graphs, title, name, conf) | ||
111 | |||
112 | def plot_file(self, datafile): | ||
113 | bname = basename(datafile) | ||
114 | name, ext = splitext(bname) | ||
115 | if ext != '.csv': | ||
116 | self.err("Warning: '%s' doesn't look like a CSV file." | ||
117 | % bname) | ||
118 | conf = decode(name) | ||
119 | tmpfile = get_data_tmpfile(datafile) | ||
120 | if tmpfile: | ||
121 | if 'spec' in conf: | ||
122 | self.plot_spec(tmpfile.name, name, conf) | ||
123 | elif 'spec2' in conf: | ||
124 | self.plot_spec2(tmpfile.name, name, conf) | ||
125 | else: | ||
126 | self.err("Skipped '%s'; unkown experiment type." | ||
127 | % bname) | ||
128 | del tmpfile # removes temp file | ||
129 | else: | ||
130 | self.err("Skipped '%s'; it dosn't appear to contain data." | ||
131 | % bname) | ||
132 | |||
133 | def default(self, _): | ||
134 | for datafile in self.args: | ||
135 | self.plot_file(datafile) | ||
136 | |||
137 | if __name__ == "__main__": | ||
138 | SchedPlotter().launch() | ||