diff options
| author | Christopher Kenna <cjk@cs.unc.edu> | 2011-10-14 01:34:59 -0400 |
|---|---|---|
| committer | Christopher Kenna <cjk@cs.unc.edu> | 2011-10-14 01:34:59 -0400 |
| commit | 51ab2aeda3c0ee94303a626c072b46f391ebdf97 (patch) | |
| tree | 5cb9840e0583b2fed1b0469e851979506796f796 | |
| parent | d872b11d85b3a502864d566c9dbae1fe1c37eb9a (diff) | |
Include level-A release times with regular release times.
Our paper includes level-A metrics in the overall scheduling overhead
metrics, so we need to manually add them back in for releases since they
take a different code path in the kernel.
| -rwxr-xr-x | plot_rtas12.py | 102 |
1 files changed, 87 insertions, 15 deletions
diff --git a/plot_rtas12.py b/plot_rtas12.py index aeba823..c248b95 100755 --- a/plot_rtas12.py +++ b/plot_rtas12.py | |||
| @@ -1,10 +1,13 @@ | |||
| 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
| 2 | 2 | ||
| 3 | import sys | 3 | import sys |
| 4 | import time | ||
| 4 | 5 | ||
| 5 | from os.path import basename | 6 | from os.path import basename |
| 6 | from os import listdir | 7 | from os import listdir |
| 7 | 8 | ||
| 9 | from tempfile import NamedTemporaryFile as Tmp | ||
| 10 | |||
| 8 | from plot import decode, Plot | 11 | from plot import decode, Plot |
| 9 | from gnuplot import curve | 12 | from gnuplot import curve |
| 10 | 13 | ||
| @@ -41,16 +44,16 @@ def gnuplot_col(col_name): | |||
| 41 | return 1 + COLS[col_name] | 44 | return 1 + COLS[col_name] |
| 42 | 45 | ||
| 43 | def get_sched_title(sched): | 46 | def get_sched_title(sched): |
| 44 | SCHEDULERS = {'MC': 'MC', | 47 | SCHEDULERS = {'MC': 'Basic', |
| 45 | 'MC-MERGE': 'MC + MT', | 48 | 'MC-MERGE': 'IM + TM', |
| 46 | 'MC-MERGE-REDIR': 'MC + MT + REDIR'} | 49 | 'MC-MERGE-REDIR': 'IM + TM + WR'} |
| 47 | return SCHEDULERS[sched] | 50 | return SCHEDULERS[sched] |
| 48 | 51 | ||
| 49 | def get_overhead_title(ov): | 52 | def get_overhead_title(ov): |
| 50 | OV = {'SCHED': '', | 53 | OV = {'SCHED': '(A + B + C)', |
| 51 | 'LVLA-SCHED': ' level-A', | 54 | 'LVLA-SCHED': '(A)', |
| 52 | 'RELEASE': '', | 55 | 'RELEASE': '(A + B + C)', |
| 53 | 'LVLA-RELEASE': ' level-A'} | 56 | 'LVLA-RELEASE': '(A)'} |
| 54 | return OV[ov] | 57 | return OV[ov] |
| 55 | 58 | ||
| 56 | def set_plot_opts(p): | 59 | def set_plot_opts(p): |
| @@ -60,14 +63,18 @@ def set_plot_opts(p): | |||
| 60 | p.size = ('8.5cm', '5.25cm') | 63 | p.size = ('8.5cm', '5.25cm') |
| 61 | p.default_style = 'linespoints lw 2.5' | 64 | p.default_style = 'linespoints lw 2.5' |
| 62 | p.default_style += ' smooth bezier' | 65 | p.default_style += ' smooth bezier' |
| 63 | p.key = 'below' | 66 | p.key = 'off' |
| 64 | p.monochrome = False | 67 | p.monochrome = False |
| 65 | p.dashed_lines = False | 68 | p.dashed_lines = False |
| 66 | p.xrange = (18, 122) | 69 | p.xrange = (18, 122) |
| 70 | p.yrange = (0, '') | ||
| 67 | 71 | ||
| 68 | for i, c in enumerate(p.curves): | 72 | for i, c in enumerate(p.curves): |
| 69 | c.style = "linespoints ls %d" % (i + 1) | 73 | c.style = "linespoints ls %d" % (i + 1) |
| 70 | 74 | ||
| 75 | # don't use yellow | ||
| 76 | p.curves[5].style = "linespoints ls 7" | ||
| 77 | |||
| 71 | p.line_styles = [ | 78 | p.line_styles = [ |
| 72 | (1, "lw 1.5 ps 0.3"), | 79 | (1, "lw 1.5 ps 0.3"), |
| 73 | (2, "lw 1.5 ps 0.3"), | 80 | (2, "lw 1.5 ps 0.3"), |
| @@ -80,21 +87,87 @@ def set_plot_opts(p): | |||
| 80 | ] | 87 | ] |
| 81 | 88 | ||
| 82 | 89 | ||
| 90 | def get_data_matrix(fname): | ||
| 91 | ret = [] | ||
| 92 | with open(fname, 'r') as f: | ||
| 93 | for row in f: | ||
| 94 | new_row = [] | ||
| 95 | for field in row.split(','): | ||
| 96 | s_field = field.strip() | ||
| 97 | try: | ||
| 98 | conv = float(s_field) | ||
| 99 | except ValueError: | ||
| 100 | conv = s_field | ||
| 101 | new_row.append(conv) | ||
| 102 | ret.append(new_row) | ||
| 103 | return ret | ||
| 104 | |||
| 105 | |||
| 106 | def include_level_a_releases(data_dir, o_type, scheduler, ycol): | ||
| 107 | fmt_f = '{0}/scheduler={1}_overhead={2}.csv' | ||
| 108 | a_fname = fmt_f.format(data_dir, scheduler, 'LVLA-RELEASE') | ||
| 109 | b_c_fname = fmt_f.format(data_dir, scheduler, 'RELEASE') | ||
| 110 | a_data = get_data_matrix(a_fname) | ||
| 111 | b_c_data = get_data_matrix(b_c_fname) | ||
| 112 | new_data = [] | ||
| 113 | |||
| 114 | for i, a_row in enumerate(a_data): | ||
| 115 | b_c_row = b_c_data[i] | ||
| 116 | # make a copy of a_row | ||
| 117 | new_row = list(a_row) | ||
| 118 | if gnuplot_col('max') == ycol: | ||
| 119 | idx = COLS['max'] | ||
| 120 | new_row[idx] = max(a_row[idx], b_c_row[idx]) | ||
| 121 | elif gnuplot_col('avg') == ycol: | ||
| 122 | avg_col = COLS['avg'] | ||
| 123 | a_samples = a_row[COLS['samples']] | ||
| 124 | b_c_samples = b_c_row[COLS['samples']] | ||
| 125 | a_filtered = a_row[COLS['filtered']] | ||
| 126 | b_c_filtered = b_c_row[COLS['filtered']] | ||
| 127 | a_avg = a_row[avg_col] | ||
| 128 | b_c_avg = b_c_row[avg_col] | ||
| 129 | n_a = a_samples - a_filtered | ||
| 130 | n_b_c = b_c_samples - b_c_filtered | ||
| 131 | new_avg = (a_avg * n_a + b_c_avg * n_b_c) / (n_a + n_b_c) | ||
| 132 | new_row[avg_col] = new_avg | ||
| 133 | else: | ||
| 134 | raise RuntimeError("Don't know how to merge this column.") | ||
| 135 | new_data.append(new_row) | ||
| 136 | f = Tmp() | ||
| 137 | for row in new_data: | ||
| 138 | f.write(', '.join(map(str, row))) | ||
| 139 | f.write('\n') | ||
| 140 | f.file.flush() | ||
| 141 | return (f.name, f) | ||
| 142 | |||
| 143 | |||
| 83 | def plot_release(data_dir, ycol, title, fname): | 144 | def plot_release(data_dir, ycol, title, fname): |
| 84 | p = Plot() | 145 | p = Plot() |
| 85 | p.output = '{0}/{1}'.format(data_dir, fname) | 146 | p.output = '{0}/{1}'.format(data_dir, fname) |
| 86 | p.format = 'pdf' | 147 | p.format = 'pdf' |
| 148 | refs = [] # need to save reference to file handle so it is not deleted | ||
| 87 | 149 | ||
| 88 | for o_type in ['RELEASE', 'LVLA-RELEASE']: | 150 | for o_type in ['RELEASE', 'LVLA-RELEASE']: |
| 89 | for sched in SCHEDULERS: | 151 | for sched in SCHEDULERS: |
| 90 | fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type) | 152 | if o_type == 'RELEASE': |
| 153 | # we have to make the regular release include the level-A | ||
| 154 | # releases | ||
| 155 | fname, ref = include_level_a_releases(data_dir, o_type, | ||
| 156 | sched, ycol) | ||
| 157 | refs.append(ref) | ||
| 158 | else: | ||
| 159 | fname = '{0}/scheduler={1}_overhead={2}.csv'.format(data_dir, sched, o_type) | ||
| 91 | ti = '{0}{1}'.format(get_sched_title(sched), get_overhead_title(o_type)) | 160 | ti = '{0}{1}'.format(get_sched_title(sched), get_overhead_title(o_type)) |
| 92 | p.curves += [curve(fname=fname, xcol=gnuplot_col('n_tasks'), | 161 | p.curves += [curve(fname=fname, xcol=gnuplot_col('n_tasks'), |
| 93 | ycol=ycol, title=ti)] | 162 | ycol=ycol, title=ti)] |
| 94 | p.xlabel = 'number of tasks' | 163 | p.xlabel = 'number of tasks' |
| 95 | p.ylabel = 'overhead (microseconds)' | 164 | p.ylabel = 'overhead (microseconds)' |
| 96 | p.title = title | ||
| 97 | set_plot_opts(p) | 165 | set_plot_opts(p) |
| 166 | if ycol == gnuplot_col('max'): | ||
| 167 | # worst-case release gets the key | ||
| 168 | p.key = 'top left' | ||
| 169 | # make the graph tall so the damn key fits | ||
| 170 | p.yrange = (0, 80) | ||
| 98 | p.gnuplot_exec() | 171 | p.gnuplot_exec() |
| 99 | 172 | ||
| 100 | def plot_sched(data_dir, ycol, title, fname): | 173 | def plot_sched(data_dir, ycol, title, fname): |
| @@ -110,7 +183,6 @@ def plot_sched(data_dir, ycol, title, fname): | |||
| 110 | ycol=ycol, title=ti)] | 183 | ycol=ycol, title=ti)] |
| 111 | p.xlabel = 'number of tasks' | 184 | p.xlabel = 'number of tasks' |
| 112 | p.ylabel = 'overhead (microseconds)' | 185 | p.ylabel = 'overhead (microseconds)' |
| 113 | p.title = title | ||
| 114 | set_plot_opts(p) | 186 | set_plot_opts(p) |
| 115 | p.gnuplot_exec() | 187 | p.gnuplot_exec() |
| 116 | 188 | ||
| @@ -120,10 +192,10 @@ def main(): | |||
| 120 | usage('missing args') | 192 | usage('missing args') |
| 121 | 193 | ||
| 122 | data_dir = sys.argv[1] | 194 | data_dir = sys.argv[1] |
| 123 | plot_sched(data_dir, gnuplot_col('max'), 'worst case scheduling overhead', 'overhead=SCHED_type=MAX.pdf') | 195 | plot_sched(data_dir, gnuplot_col('max'), 'worst-case scheduling overhead', 'overhead=SCHED_type=MAX.pdf') |
| 124 | plot_release(data_dir, gnuplot_col('max'), 'worst case release overhead', 'overhead=RELEASE_type=MAX.pdf') | 196 | plot_release(data_dir, gnuplot_col('max'), 'worst-case release overhead', 'overhead=RELEASE_type=MAX.pdf') |
| 125 | plot_sched(data_dir, gnuplot_col('avg'), 'average scheduling overhead', 'overhead=SCHED_type=AVG.pdf') | 197 | plot_sched(data_dir, gnuplot_col('avg'), 'average-case scheduling overhead', 'overhead=SCHED_type=AVG.pdf') |
| 126 | plot_release(data_dir, gnuplot_col('avg'), 'average release overhead', 'overhead=RELEASE_type=AVG.pdf') | 198 | plot_release(data_dir, gnuplot_col('avg'), 'average-case release overhead', 'overhead=RELEASE_type=AVG.pdf') |
| 127 | 199 | ||
| 128 | if __name__ == '__main__': | 200 | if __name__ == '__main__': |
| 129 | main() | 201 | main() |
