aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xpm_data_analysis/pm_data_analyzer.py173
-rw-r--r--pm_data_analysis/pmserialize.py25
-rw-r--r--test_get_arrays.py21
3 files changed, 198 insertions, 21 deletions
diff --git a/pm_data_analysis/pm_data_analyzer.py b/pm_data_analysis/pm_data_analyzer.py
new file mode 100755
index 0000000..6862f98
--- /dev/null
+++ b/pm_data_analysis/pm_data_analyzer.py
@@ -0,0 +1,173 @@
1#!/usr/bin/env python
2#
3# Preemption and migration overheads analysis.
4# Take a single-task-set-size file and generate max / avg for the valid
5# samples for preemption and different kinds of migration
6#
7# Save computed valid overheads and print a file suitable for processing
8# using gnuplot / tikz / lua
9
10import sys
11import numpy as np
12
13# preemption and migration C data exchanger
14import pm
15import pmserialize as pms
16
17from optparse import OptionParser
18
19class Overhead:
20 def __init__(self):
21 self.overheads = []
22 self.index = 0
23
24 def __iter__(self):
25 return self
26
27 def next(self):
28 if self.index == len(self.overheads):
29 self.index = 0
30 raise StopIteration
31 self.index += 1
32 return self.overheads[self.index - 1]
33
34 def add(self, ovd_vector, label):
35 self.overheads.append([ovd_vector, label])
36
37
38class InterQuartileRange:
39 def __init__(self, low, high):
40 self.low = low
41 self.high = high
42
43 def remOutliers(self, vector):
44 # discard points etc
45 return vector
46
47def read_valid_data(filename, coresL2, valid_ovds):
48 suff = filename.find('.raw')
49 if suff == -1:
50 print "Warning: bad suffix, I may fail in finding the right files"
51
52 nf = filename[0:suff] + '_preemption.vbin'
53 valid_ovds.add(pms.unpickl_it(nf), 'preemtion')
54 nf = filename[0:suff] + '_onchip.vbin'
55 valid_ovds.add(pms.unpickl_it(nf), 'onchip')
56 nf = filename[0:suff] + '_offchip.vbin'
57 valid_ovds.add(pms.unpickl_it(nf), 'offchip')
58 if coresL2 != 0:
59 nf = filename[0:suff] + '_l2cache.vbin'
60 valid_ovds.add(pms.unpickl_it(nf), 'l2cache')
61
62
63def process_raw_data(filename, coresL2, coresC, valid_ovds):
64 # initialize pmmodule
65 pm.load(filename, coresL2, coresC)
66
67 ovds = Overhead()
68
69 # get overheads
70 ovds.add(pm.getPreemption(), 'preemption')
71 ovds.add(pm.getOnChipMigration(), 'onchip')
72 ovds.add(pm.getOffChipMigration(), 'offchip')
73 if coresL2 != 0:
74 ovds.add(pm.getL2Migration(), 'l2cache')
75
76 if verbose:
77 for i in ovds:
78 print i[0], i[1]
79
80 # instance the statistical analizer to remove outliers
81 sd = InterQuartileRange(25,75)
82
83 for i in ovds:
84 valid_ovds.add(sd.remOutliers(i[0]), i[1])
85
86 # serialize valid overheads
87 for i in valid_ovds:
88 suff = filename.find('.raw')
89 if suff == -1:
90 print "Warning: ugly name for outfiles"
91
92 curf = filename[0:suff] + '_' + i[1] + '.vbin'
93 pms.pickl_it(i[0], curf)
94
95 del ovds
96
97# tssize_char is the number of chars used to represent the tssize
98# e.g., 050 -> tsize_char = 3
99def analize_data(valid_ovds, filename, tssize_char):
100 suff = filename.find('.raw')
101 if suff == -1:
102 print filename
103 print "Warning: ugly name for outfiles; check number of tasks!"
104
105 nf = filename[0:suff - tssize_char - 1] + '.csv'
106 csvf = open(nf, 'a')
107
108 # taskset size
109 pms.cvs_it(csvf, filename[suff - tssize_char:suff])
110
111 for i in valid_ovds:
112 # overhead type
113 pms.cvs_it(csvf, i[1])
114 # data (atm just overhead, not length)
115 vector = i[0][:,0]
116 if vector != []:
117 pms.cvs_it(csvf, "%5.5f" % np.max(vector))
118 pms.cvs_it(csvf, "%5.5f" % np.average(vector))
119 else:
120 pms.cvs_it(csvf, "[]")
121 pms.cvs_it(csvf, "[]")
122
123 csvf.close()
124
125# filename-extension convention to get "pretty" output filenames
126# .raw for raw bin data
127# .vbin for valid overheads
128# .csv for processed final data
129def main():
130 usage = "Usage: %prog [options] filename"
131 description = "FILENAME is where the .raw overhead data are. Filename \
132 and the path to it also gives the base path and filename for the \
133 files that contains already processed overheads and the directory \
134 where to save the output data."
135 parser = OptionParser(usage=usage, description=description)
136 parser.add_option("-l", "--cores-per-l2", dest="coresL2",
137 action="store", type="int", default="0",
138 help="number of cores per L2 cache; "
139 "if all cores share the same L2 (i.e., no L3) set this to 0 "
140 "(default = 0)")
141 parser.add_option("-c", "--cores-per-chip", dest="coresC",
142 action="store", type="int", default="4",
143 help="number of cores per chip (default = 4)")
144 parser.add_option("-r", "--read-valid-data", dest="read_valid",
145 action="store_true", default=False,
146 help="read already processed data from file")
147 parser.add_option("-v", "--verbose", dest="verbose",
148 action="store_true", default=False,
149 help="Be verbose")
150 (options, args) = parser.parse_args()
151 if len(args) != 1:
152 parser.error("Argument missing")
153 sys.exit(-1)
154
155 valid_ovds = Overhead()
156
157 global verbose
158 if options.verbose:
159 verbose = 1
160 else:
161 verbose = 0
162
163 if options.read_valid:
164 read_valid_data(args[0], options.coresL2, valid_ovds)
165 else:
166 process_raw_data(args[0], options.coresL2, options.coresC,
167 valid_ovds)
168
169 analize_data(valid_ovds, args[0], 3)
170
171if __name__ == '__main__':
172 main()
173
diff --git a/pm_data_analysis/pmserialize.py b/pm_data_analysis/pmserialize.py
new file mode 100644
index 0000000..14e0f3b
--- /dev/null
+++ b/pm_data_analysis/pmserialize.py
@@ -0,0 +1,25 @@
1#!/usr/bin/env python
2
3import cPickle
4import csv
5
6# http://en.wikipedia.org/wiki/Picolit
7def pickl_it(vector, filename):
8 f = open(filename, 'w')
9 cPickle.dump(vector, f)
10 f.close()
11
12def unpickl_it(filename):
13 f = open(filename, 'r')
14 vector = cPickle.load(f)
15 f.close()
16 return vector
17
18# FIXME the one char one comma format from csv
19# is not very "human readable" :|
20def cvs_it(file, string):
21 wr = csv.writer(file)
22 wr.writerow(string)
23
24def uncvs_it(file, string):
25 return None
diff --git a/test_get_arrays.py b/test_get_arrays.py
deleted file mode 100644
index 74af08e..0000000
--- a/test_get_arrays.py
+++ /dev/null
@@ -1,21 +0,0 @@
1#!/usr/bin/python
2import sys, pm
3
4args = sys.argv[1:]
5if len(args) != 1:
6 print "Filename required"
7 sys.exit(-1)
8
9pm.load(args[0],0,4)
10x = pm.getPreemption()
11y = pm.getOnChipMigration()
12z = pm.getL2Migration()
13w = pm.getOffChipMigration()
14print "preemption: "
15print x
16print "samechip:"
17print y
18print "l2:"
19print z
20print "offchip"
21print w