aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-10-29 09:59:35 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2012-10-29 09:59:35 -0400
commit5b50c58ea4881dd185897dfa93860c60f551d815 (patch)
tree1eee3271b5ab9fad7774a073110287b27e4d32fd
parentf1e90e1a5f7b148cf8113fe463615bd95d5bf26d (diff)
Prettied up parse output.
-rw-r--r--config/config.example.py16
-rw-r--r--parse/ft.py1
-rw-r--r--parse/point.py11
-rw-r--r--parse/sched.py60
-rw-r--r--parse/tuple_table.py5
-rwxr-xr-x[-rw-r--r--]plot_exps.py115
6 files changed, 182 insertions, 26 deletions
diff --git a/config/config.example.py b/config/config.example.py
index 06f06b6..50d30ba 100644
--- a/config/config.example.py
+++ b/config/config.example.py
@@ -41,16 +41,22 @@ PARAMS = {'sched' : 'scheduler',
41 'kernel' : 'uname'} 41 'kernel' : 'uname'}
42 42
43SCHED_EVENTS = range(501, 513) 43SCHED_EVENTS = range(501, 513)
44BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS'] 44BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS', 'SEND_RESCHED']
45BASE_EVENTS += ['CQ_ENQUEUE_READ', 'CQ_ENQUEUE_FLUSH', 'CQ_SUBMIT_WORK',
46 'CQ_LOOP_WORK_CHECK', 'CQ_LOOP_PEACE_OUT', 'CQ_LOOP_BRANCH',
47 'CQ_WORK_DO_WORK', 'CQ_WORK_NOTIFY', 'CQ_PHASE_WAIT']
45 48
46# Expand for mixed-crit 49# Expand for mixed-crit
47# CRIT_EVENTS = ['LVL{}_SCHED', 'LVL{}_RELEASE'] 50# TODO don't use split
48# CRIT_LEVELS = ['A', 'B', 'C'] 51CRIT_EVENTS = ['LVL{}_SCHED', 'LVL{}_RELEASE']
49# BASE_EVENTS += [s.format(l) for (l,s) in 52CRIT_LEVELS = ['A', 'B', 'C']
50# itertools.product(CRIT_LEVELS, CRIT_EVENTS)] 53BASE_EVENTS += [s.format(l) for (l,s) in
54 itertools.product(CRIT_LEVELS, CRIT_EVENTS)]
51 55
52ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in 56ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in
53 itertools.product(BASE_EVENTS, ["START","END"])] 57 itertools.product(BASE_EVENTS, ["START","END"])]
58ALL_EVENTS += ['RELEASE_LATENCY']
59BASE_EVENTS += ['RELEASE_LATENCY']
54 60
55valid = True 61valid = True
56for repo, loc in REPOS.items(): 62for repo, loc in REPOS.items():
diff --git a/parse/ft.py b/parse/ft.py
index 2c2b597..feb338f 100644
--- a/parse/ft.py
+++ b/parse/ft.py
@@ -41,6 +41,7 @@ def get_ft_output(data_dir, out_dir, force=False):
41 # Analyze will summarize those 41 # Analyze will summarize those
42 # todo pass in f 42 # todo pass in f
43 cmd_arr = [conf.BINS['analyze']] 43 cmd_arr = [conf.BINS['analyze']]
44 print("cmd arr: %s-%s" % (cmd_arr, bins))
44 cmd_arr.extend(bins) 45 cmd_arr.extend(bins)
45 with open(output_file, "w") as f: 46 with open(output_file, "w") as f:
46 subprocess.call(cmd_arr, cwd=out_dir, stdout=f, stderr=err_file) 47 subprocess.call(cmd_arr, cwd=out_dir, stdout=f, stderr=err_file)
diff --git a/parse/point.py b/parse/point.py
index 30fcd97..8fdd115 100644
--- a/parse/point.py
+++ b/parse/point.py
@@ -16,7 +16,14 @@ def make_typemap():
16 return copy.deepcopy(default_typemap) 16 return copy.deepcopy(default_typemap)
17 17
18def dict_str(adict, sep = "\n"): 18def dict_str(adict, sep = "\n"):
19 return sep.join(["%s: %s" % (k, str(v)) for (k,v) in sorted(adict.iteritems())]) 19 def num_str(v):
20 try:
21 float(v)
22 return "%6.3f" % v
23 except:
24 return v
25 size = 20 if sep == "\n" else 4
26 return sep.join([("%" + str(size) + "s: %9s") % (k, num_str(v)) for (k,v) in sorted(adict.iteritems())])
20 27
21class Measurement(object): 28class Measurement(object):
22 def __init__(self, id = None, kv = {}): 29 def __init__(self, id = None, kv = {}):
@@ -52,7 +59,7 @@ class Measurement(object):
52 self.stats[type] = value 59 self.stats[type] = value
53 60
54 def __str__(self): 61 def __str__(self):
55 return "<Measurement-%s> %s" % (self.id, dict_str(self.stats, " ")) 62 return "%s" % dict_str(self.stats, " ")
56 63
57 64
58class Summary(Measurement): 65class Summary(Measurement):
diff --git a/parse/sched.py b/parse/sched.py
index 7dd80e0..cbb051e 100644
--- a/parse/sched.py
+++ b/parse/sched.py
@@ -1,5 +1,6 @@
1""" 1"""
2TODO: No longer very pythonic, lot of duplicate code 2TODO: No longer very pythonic, lot of duplicate code
3print out task execution times
3""" 4"""
4 5
5import config.config as conf 6import config.config as conf
@@ -9,6 +10,7 @@ import numpy as np
9import subprocess 10import subprocess
10 11
11from collections import namedtuple,defaultdict 12from collections import namedtuple,defaultdict
13from operator import methodcaller
12from point import Measurement,Type 14from point import Measurement,Type
13 15
14PARAM_RECORD = r"(?P<RECORD>" +\ 16PARAM_RECORD = r"(?P<RECORD>" +\
@@ -29,12 +31,14 @@ TARDY_RECORD = r"(?P<RECORD>" +\
29 r"(?P<MISSES>[\d\.]+))" 31 r"(?P<MISSES>[\d\.]+))"
30COMPLETION_RECORD = r"(?P<RECORD>" +\ 32COMPLETION_RECORD = r"(?P<RECORD>" +\
31 r"COMPLETION.*?(?P<PID>\d+)/.*?" +\ 33 r"COMPLETION.*?(?P<PID>\d+)/.*?" +\
32 r"exec.*?(?P<EXEC>[\d\.]+)ms.*?" +\ 34 r"exec:.*?(?P<EXEC>[\d\.]+)ms.*?" +\
33 r"flush.*?(?P<FLUSH>[\d\.]+)ms.*?" +\ 35 r"flush:.*?(?P<FLUSH>[\d\.]+)ms.*?" +\
34 r"load.*?(?P<LOAD>[\d\.]+)ms)" 36 r"flush_work:.*?(?P<FLUSH_WORK>[\d]+).*?" +\
37 r"load:.*?(?P<LOAD>[\d\.]+)ms.*?" +\
38 r"load_work:.*?(?P<LOAD_WORK>[\d]+))"
35 39
36TaskConfig = namedtuple('TaskConfig', ['cpu','wcet','period','type','level']) 40TaskConfig = namedtuple('TaskConfig', ['cpu','wcet','period','type','level'])
37Task = namedtuple('Task', ['pid', 'config']) 41Task = namedtuple('Task', ['pid', 'config', 'run'])
38 42
39class LeveledArray(object): 43class LeveledArray(object):
40 """ 44 """
@@ -86,7 +90,7 @@ def get_tasks(data):
86 float(match.group('WCET')), 90 float(match.group('WCET')),
87 float(match.group('PERIOD')), 91 float(match.group('PERIOD')),
88 match.group("CLASS"), 92 match.group("CLASS"),
89 match.group("LEVEL"))) 93 match.group("LEVEL")), [])
90 if not (t.config.period and t.pid): 94 if not (t.config.period and t.pid):
91 raise Exception() 95 raise Exception()
92 ret += [t] 96 ret += [t]
@@ -144,15 +148,16 @@ def extract_tardy_vals(task_dict, data, exp_point):
144 max_tards.add(t, max_tard / t.config.period) 148 max_tards.add(t, max_tard / t.config.period)
145 ratios.add(t, misses / jobs) 149 ratios.add(t, misses / jobs)
146 150
147 ratios.write_measurements(exp_point) 151 map(methodcaller('write_measurements', exp_point),
148 avg_tards.write_measurements(exp_point) 152 [ratios, avg_tards, max_tards])
149 max_tards.write_measurements(exp_point)
150 153
151# TODO: rename 154# TODO: rename
152def extract_variance(task_dict, data, exp_point): 155def extract_variance(task_dict, data, exp_point):
153 varz = LeveledArray("exec-variance") 156 varz = LeveledArray("exec-variance")
154 flushes = LeveledArray("cache-flush") 157 flushes = LeveledArray("cache-flush")
155 loads = LeveledArray("cache-load") 158 loads = LeveledArray("cache-load")
159 fworks = LeveledArray("flush-work")
160 lworks = LeveledArray("load-work")
156 161
157 completions = defaultdict(lambda: []) 162 completions = defaultdict(lambda: [])
158 missed = defaultdict(lambda: int()) 163 missed = defaultdict(lambda: int())
@@ -163,11 +168,17 @@ def extract_variance(task_dict, data, exp_point):
163 duration = float(match.group("EXEC")) 168 duration = float(match.group("EXEC"))
164 load = float(match.group("LOAD")) 169 load = float(match.group("LOAD"))
165 flush = float(match.group("FLUSH")) 170 flush = float(match.group("FLUSH"))
171 lwork = int(match.group("LOAD_WORK"))
172 fwork = int(match.group("FLUSH_WORK"))
166 173
167 if load: 174 if load:
168 loads.add(task_dict[pid], load) 175 loads.add(task_dict[pid], load)
176 lworks.add(task_dict[pid], lwork)
177 if not lwork: raise Exception()
169 if flush: 178 if flush:
170 flushes.add(task_dict[pid], flush) 179 flushes.add(task_dict[pid], flush)
180 fworks.add(task_dict[pid], fwork)
181 if not fwork: raise Exception()
171 182
172 # Last (exit) record often has exec time of 0 183 # Last (exit) record often has exec time of 0
173 missed[pid] += not bool(duration) 184 missed[pid] += not bool(duration)
@@ -181,6 +192,9 @@ def extract_variance(task_dict, data, exp_point):
181 completions[pid] += [duration] 192 completions[pid] += [duration]
182 193
183 for pid, durations in completions.iteritems(): 194 for pid, durations in completions.iteritems():
195 # TODO: not this, please
196 task_dict[pid].run.append(Measurement(pid).from_array(durations))
197
184 job_times = np.array(durations) 198 job_times = np.array(durations)
185 mean = job_times.mean() 199 mean = job_times.mean()
186 200
@@ -194,14 +208,15 @@ def extract_variance(task_dict, data, exp_point):
194 208
195 varz.add(task_dict[pid], corrected) 209 varz.add(task_dict[pid], corrected)
196 210
197 varz.write_measurements(exp_point) 211 if exp_point:
198 flushes.write_measurements(exp_point) 212 map(methodcaller('write_measurements', exp_point),
199 loads.write_measurements(exp_point) 213 [varz, flushes, loads, fworks, lworks])
200 214
201def config_exit_stats(task_dict, data): 215def config_exit_stats(task_dict, data):
202 # Dictionary of task exit measurements by pid 216 # # Dictionary of task exit measurements by pid