diff options
| -rwxr-xr-x | compact_pm_ovd.py | 111 | ||||
| -rwxr-xr-x | plot_pm.py | 194 |
2 files changed, 305 insertions, 0 deletions
diff --git a/compact_pm_ovd.py b/compact_pm_ovd.py new file mode 100755 index 0000000..5024d61 --- /dev/null +++ b/compact_pm_ovd.py | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | #!/usr/bin/env python | ||
| 2 | |||
| 3 | from os.path import splitext, basename, dirname | ||
| 4 | from optparse import OptionParser | ||
| 5 | |||
| 6 | def decode(name): | ||
| 7 | params = {} | ||
| 8 | parts = name.split('_') | ||
| 9 | for p in parts: | ||
| 10 | kv = p.split('=') | ||
| 11 | k = kv[0] | ||
| 12 | v = kv[1] if len(kv) > 1 else None | ||
| 13 | params[k] = v | ||
| 14 | return params | ||
| 15 | |||
| 16 | |||
| 17 | def build_name(dirname, conf, wss_list): | ||
| 18 | if dirname == '': | ||
| 19 | dirname = '.' | ||
| 20 | outname = dirname + '/' | ||
| 21 | if 'hard' in conf: | ||
| 22 | outname += 'hard' | ||
| 23 | else: | ||
| 24 | outname += 'soft' | ||
| 25 | outname += '_pm_plugin=' + conf['plugin'] + '_dist=' + conf['dist'] | ||
| 26 | # atm we use only uniform for PM (we also use only light, but...) | ||
| 27 | if 'light' in conf: | ||
| 28 | outname += '_light' | ||
| 29 | elif 'medium' in conf: | ||
| 30 | outname += '_medium' | ||
| 31 | elif 'heavy' in conf: | ||
| 32 | outname += '_heavy' | ||
| 33 | |||
| 34 | outname += '_wss=' | ||
| 35 | for wss in wss_list: | ||
| 36 | if wss != wss_list[len(wss_list) - 1]: | ||
| 37 | outname += str(wss) + ',' | ||
| 38 | else: | ||
| 39 | outname += str(wss) | ||
| 40 | outname += '_ovd=' + conf['ovd'] + '.csv' | ||
| 41 | return outname | ||
| 42 | |||
| 43 | |||
| 44 | class WSSCompactor(): | ||
| 45 | def __init__(self): | ||
| 46 | self.ovhead_table = {} | ||
| 47 | self.wss_list = [] | ||
| 48 | |||
| 49 | def add_wss(self, wss): | ||
| 50 | self.wss_list.append(int(wss)) | ||
| 51 | |||
| 52 | def read_csv(self, datafile): | ||
| 53 | csvf = open(datafile, 'r') | ||
| 54 | # csvf format is: tss, max, avg | ||
| 55 | for line in csvf: | ||
| 56 | tmp = line.split(', ') | ||
| 57 | if tmp[0] in self.ovhead_table.keys(): | ||
| 58 | self.ovhead_table[tmp[0]] += [tmp[1], tmp[2].rstrip('\n')] | ||
| 59 | else: | ||
| 60 | self.ovhead_table[tmp[0]] = [tmp[1], tmp[2].rstrip('\n')] | ||
| 61 | csvf.close() | ||
| 62 | |||
| 63 | def write_csv(self, dirname, conf): | ||
| 64 | self.wss_list.sort() | ||
| 65 | outname = build_name(dirname, conf, self.wss_list) | ||
| 66 | csvf = open(outname, 'w') | ||
| 67 | csvf.write('# preemption and migration overhead for ' + \ | ||
| 68 | conf['plugin'] + '\n') | ||
| 69 | |||
| 70 | wstr = '# tssize, ' | ||
| 71 | for wss in self.wss_list: | ||
| 72 | wstr += 'wss=' + str(wss) + ':(max, avg), ' | ||
| 73 | csvf.write(wstr[0:-2] + '\n') | ||
| 74 | |||
| 75 | tkeys = self.ovhead_table.keys() | ||
| 76 | for i in range(0,len(tkeys)): | ||
| 77 | tkeys[i] = int(tkeys[i]) | ||
| 78 | tkeys.sort() | ||
| 79 | |||
| 80 | for key in tkeys: | ||
| 81 | wstr = str(key) + ', ' | ||
| 82 | for value in self.ovhead_table[str(key)]: | ||
| 83 | wstr += value + ', ' | ||
| 84 | wstr = wstr[0:-2] | ||
| 85 | csvf.write(wstr + '\n') | ||
| 86 | |||
| 87 | csvf.close() | ||
| 88 | |||
| 89 | def main(args): | ||
| 90 | wsscmpctr = WSSCompactor() | ||
| 91 | for datafile in args: | ||
| 92 | bname = basename(datafile) | ||
| 93 | fname, ext = splitext(bname) | ||
| 94 | if ext != '.csv': | ||
| 95 | self.err("Warning: '%s' doesn't look like a CSV file." | ||
| 96 | % bname) | ||
| 97 | conf = decode(fname) | ||
| 98 | wsscmpctr.add_wss(conf['wss']) | ||
| 99 | wsscmpctr.read_csv(datafile) | ||
| 100 | |||
| 101 | # assume all files in same directory and same kind of overheads | ||
| 102 | wsscmpctr.write_csv(dirname(datafile), conf) | ||
| 103 | |||
| 104 | if __name__ == "__main__": | ||
| 105 | usage = "Usage: %prog list-of-file" | ||
| 106 | parser = OptionParser(usage=usage) | ||
| 107 | (options, args) = parser.parse_args() | ||
| 108 | if len(args) < 1: | ||
| 109 | parser.error("Argument missing") | ||
| 110 | sys.exit(-1) | ||
| 111 | main(args) | ||
diff --git a/plot_pm.py b/plot_pm.py new file mode 100755 index 0000000..7388dce --- /dev/null +++ b/plot_pm.py | |||
| @@ -0,0 +1,194 @@ | |||
| 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(None, '--shared-l3', action='store_true', dest='sharedL3'), | ||
| 11 | o('-f', '--format', action='store', dest='format', type='choice', | ||
| 12 | choices=FORMATS, help='output format'), | ||
| 13 | o(None, '--paper', action='store_true', dest='paper'), | ||
| 14 | o(None, '--wide', action='store_true', dest='wide'), | ||
| 15 | ] | ||
| 16 | |||
| 17 | defaults = { | ||
| 18 | 'sharedL3' : False, | ||
| 19 | 'format' : 'show', | ||
| 20 | 'xrange' : (49.5, 250.5), | ||
| 21 | 'yrange' : (0, 500.05), | ||
| 22 | 'xticks' : (0, 10), | ||
| 23 | 'yticks' : (0, 50), | ||
| 24 | 'title' : None, | ||
| 25 | 'xlabel' : 'number of tasks', | ||
| 26 | 'ylabel' : 'overhead (us)', | ||
| 27 | 'paper' : False, | ||
| 28 | 'split' : False, | ||
| 29 | 'wide' : False, | ||
| 30 | } | ||
| 31 | |||
| 32 | def decode(name): | ||
| 33 | params = {} | ||
| 34 | parts = name.split('_') | ||
| 35 | for p in parts: | ||
| 36 | kv = p.split('=') | ||
| 37 | k = kv[0] | ||
| 38 | v = kv[1] if len(kv) > 1 else None | ||
| 39 | params[k] = v | ||
| 40 | return params | ||
| 41 | |||
| 42 | def get_data_tmpfile(datafile): | ||
| 43 | """Removes all comments form datafile, stores result in a temp file. | ||
| 44 | The temp file is returned.""" | ||
| 45 | count = 0 | ||
| 46 | f = open(datafile, 'r') | ||
| 47 | d = Tmp() | ||
| 48 | for line in f: | ||
| 49 | if len(line) > 1 and line[0] != '#': | ||
| 50 | d.write(line) | ||
| 51 | count += 1 | ||
| 52 | f.close() | ||
| 53 | d.flush() | ||
| 54 | if count > 0: | ||
| 55 | return d | ||
| 56 | else: | ||
| 57 | del d # removes temp file | ||
| 58 | return None | ||
| 59 | |||
| 60 | def scenario_heading(conf, want_period=False, sharedL3=False): | ||
| 61 | ovd_type = 'unknowkn overhead' | ||
| 62 | if 'ovd' in conf: | ||
| 63 | if conf['ovd'] == 'preemption': | ||
| 64 | ovd_type = 'Preemption ovhead' | ||
| 65 | elif conf['ovd'] == 'onchip': | ||
| 66 | if sharedL3: | ||
| 67 | ovd_type = 'Shared L3 migration ovhead' | ||
| 68 | else: | ||
| 69 | ovd_type = 'Shared L2 migration ovhead' | ||
| 70 | elif conf['ovd'] == 'l2cache': | ||
| 71 | ovd_type = 'Shared L2 migration ovhead' | ||
| 72 | elif conf['ovd'] == 'offchip': | ||
| 73 | ovd_type = 'Off Chip migration ovhead' | ||
| 74 | |||
| 75 | dist = 'unknown distribution' | ||
| 76 | if 'dist' in conf: | ||
| 77 | if conf['dist'] == 'uni': | ||
| 78 | dist = 'utilization uniformly ' | ||
| 79 | if 'light' in conf: | ||
| 80 | dist = dist + 'in [0.001, 0.1]' | ||
| 81 | elif 'medium' in conf: | ||
| 82 | dist = dist + 'in [0.1, 0.4]' | ||
| 83 | elif 'heavy' in conf: | ||
| 84 | dist = dist + 'in [0.5, 0.9]' | ||
| 85 | elif conf['dist'] == 'bimo': | ||
| 86 | dist = 'util. bimodially ' | ||
| 87 | if 'light' in conf: | ||
| 88 | dist = dist + 'in [0.001, 0.5] (8/9) and [0.5, 0.9] (1/9)' | ||
| 89 | elif 'medium' in conf: | ||
| 90 | dist = dist + 'in [0.001, 0.5] (6/9) and [0.5, 0.9] (3/9)' | ||
| 91 | elif 'heavy' in conf: | ||
| 92 | dist = dist + 'in [0.001, 0.5] (4/9) and [0.5, 0.9] (5/9)' | ||
| 93 | if want_period: | ||
| 94 | if '33' in conf: | ||
| 95 | dist += '; period uniformly in [3, 33]' | ||
| 96 | elif '250' in conf: | ||
| 97 | dist += '; period uniformly in [50, 250]' | ||
| 98 | else: | ||
| 99 | dist += '; period uniformly in [10, 100]' | ||
| 100 | |||
| 101 | return ovd_type + '; ' + dist | ||
| 102 | |||
| 103 | class PmPlotter(defapp.App): | ||
| 104 | def __init__(self): | ||
| 105 | defapp.App.__init__(self, options, defaults, no_std_opts=True) | ||
| 106 | |||
| 107 | def plot(self, graphs, title, name, conf, **xtra): | ||
| 108 | gnuplot(graphs, title=title, | ||
| 109 | xlabel=self.options.xlabel, | ||
| 110 | ylabel=self.options.ylabel + | ||
| 111 | (' [avg]' if 'soft' in conf else ' [max]'), | ||
| 112 | xrange=self.options.xrange, | ||
