comparison contrib/analyze_brprob.py @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
69 69
70 from math import * 70 from math import *
71 71
72 counter_aggregates = set(['combined', 'first match', 'DS theory', 72 counter_aggregates = set(['combined', 'first match', 'DS theory',
73 'no prediction']) 73 'no prediction'])
74 hot_threshold = 10
74 75
75 def percentage(a, b): 76 def percentage(a, b):
76 return 100.0 * a / b 77 return 100.0 * a / b
77 78
78 def average(values): 79 def average(values):
129 # save the file 130 # save the file
130 if write_def_file: 131 if write_def_file:
131 with open(self.path, 'w+') as f: 132 with open(self.path, 'w+') as f:
132 for l in modified_lines: 133 for l in modified_lines:
133 f.write(l + '\n') 134 f.write(l + '\n')
135 class Heuristics:
136 def __init__(self, count, hits, fits):
137 self.count = count
138 self.hits = hits
139 self.fits = fits
134 140
135 class Summary: 141 class Summary:
136 def __init__(self, name): 142 def __init__(self, name):
137 self.name = name 143 self.name = name
138 self.branches = 0 144 self.edges= []
139 self.successfull_branches = 0 145
140 self.count = 0 146 def branches(self):
141 self.hits = 0 147 return len(self.edges)
142 self.fits = 0 148
149 def hits(self):
150 return sum([x.hits for x in self.edges])
151
152 def fits(self):
153 return sum([x.fits for x in self.edges])
154
155 def count(self):
156 return sum([x.count for x in self.edges])
157
158 def successfull_branches(self):
159 return len([x for x in self.edges if 2 * x.hits >= x.count])
143 160
144 def get_hitrate(self): 161 def get_hitrate(self):
145 return 100.0 * self.hits / self.count 162 return 100.0 * self.hits() / self.count()
146 163
147 def get_branch_hitrate(self): 164 def get_branch_hitrate(self):
148 return 100.0 * self.successfull_branches / self.branches 165 return 100.0 * self.successfull_branches() / self.branches()
149 166
150 def count_formatted(self): 167 def count_formatted(self):
151 v = self.count 168 v = self.count()
152 for unit in ['','K','M','G','T','P','E','Z']: 169 for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']:
153 if v < 1000: 170 if v < 1000:
154 return "%3.2f%s" % (v, unit) 171 return "%3.2f%s" % (v, unit)
155 v /= 1000.0 172 v /= 1000.0
156 return "%.1f%s" % (v, 'Y') 173 return "%.1f%s" % (v, 'Y')
157 174
175 def count(self):
176 return sum([x.count for x in self.edges])
177
158 def print(self, branches_max, count_max, predict_def): 178 def print(self, branches_max, count_max, predict_def):
179 # filter out most hot edges (if requested)
180 self.edges = sorted(self.edges, reverse = True, key = lambda x: x.count)
181 if args.coverage_threshold != None:
182 threshold = args.coverage_threshold * self.count() / 100
183 edges = [x for x in self.edges if x.count < threshold]
184 if len(edges) != 0:
185 self.edges = edges
186
159 predicted_as = None 187 predicted_as = None
160 if predict_def != None and self.name in predict_def.predictors: 188 if predict_def != None and self.name in predict_def.predictors:
161 predicted_as = predict_def.predictors[self.name] 189 predicted_as = predict_def.predictors[self.name]
162 190
163 print('%-40s %8i %5.1f%% %11.2f%% %7.2f%% / %6.2f%% %14i %8s %5.1f%%' % 191 print('%-40s %8i %5.1f%% %11.2f%% %7.2f%% / %6.2f%% %14i %8s %5.1f%%' %
164 (self.name, self.branches, 192 (self.name, self.branches(),
165 percentage(self.branches, branches_max), 193 percentage(self.branches(), branches_max),
166 self.get_branch_hitrate(), 194 self.get_branch_hitrate(),
167 self.get_hitrate(), 195 self.get_hitrate(),
168 percentage(self.fits, self.count), 196 percentage(self.fits(), self.count()),
169 self.count, self.count_formatted(), 197 self.count(), self.count_formatted(),
170 percentage(self.count, count_max)), end = '') 198 percentage(self.count(), count_max)), end = '')
171 199
172 if predicted_as != None: 200 if predicted_as != None:
173 print('%12i%% %5.1f%%' % (predicted_as, 201 print('%12i%% %5.1f%%' % (predicted_as,
174 self.get_hitrate() - predicted_as), end = '') 202 self.get_hitrate() - predicted_as), end = '')
203 else:
204 print(' ' * 20, end = '')
205
206 # print details about the most important edges
207 if args.coverage_threshold == None:
208 edges = [x for x in self.edges[:100] if x.count * hot_threshold > self.count()]
209 if args.verbose:
210 for c in edges:
211 r = 100.0 * c.count / self.count()
212 print(' %.0f%%:%d' % (r, c.count), end = '')
213 elif len(edges) > 0:
214 print(' %0.0f%%:%d' % (100.0 * sum([x.count for x in edges]) / self.count(), len(edges)), end = '')
215
175 print() 216 print()
176 217
177 class Profile: 218 class Profile:
178 def __init__(self, filename): 219 def __init__(self, filename):
179 self.filename = filename 220 self.filename = filename
183 def add(self, name, prediction, count, hits): 224 def add(self, name, prediction, count, hits):
184 if not name in self.heuristics: 225 if not name in self.heuristics:
185 self.heuristics[name] = Summary(name) 226 self.heuristics[name] = Summary(name)
186 227
187 s = self.heuristics[name] 228 s = self.heuristics[name]
188 s.branches += 1 229
189
190 s.count += count
191 if prediction < 50: 230 if prediction < 50:
192 hits = count - hits 231 hits = count - hits
193 remaining = count - hits 232 remaining = count - hits
194 if hits >= remaining: 233 fits = max(hits, remaining)
195 s.successfull_branches += 1 234
196 235 s.edges.append(Heuristics(count, hits, fits))
197 s.hits += hits
198 s.fits += max(hits, remaining)
199 236
200 def add_loop_niter(self, niter): 237 def add_loop_niter(self, niter):
201 if niter > 0: 238 if niter > 0:
202 self.niter_vector.append(niter) 239 self.niter_vector.append(niter)
203 240
204 def branches_max(self): 241 def branches_max(self):
205 return max([v.branches for k, v in self.heuristics.items()]) 242 return max([v.branches() for k, v in self.heuristics.items()])
206 243
207 def count_max(self): 244 def count_max(self):
208 return max([v.count for k, v in self.heuristics.items()]) 245 return max([v.count() for k, v in self.heuristics.items()])
209 246
210 def print_group(self, sorting, group_name, heuristics, predict_def): 247 def print_group(self, sorting, group_name, heuristics, predict_def):
211 count_max = self.count_max() 248 count_max = self.count_max()
212 branches_max = self.branches_max() 249 branches_max = self.branches_max()
213 250
214 sorter = lambda x: x.branches 251 sorter = lambda x: x.branches()
215 if sorting == 'branch-hitrate': 252 if sorting == 'branch-hitrate':
216 sorter = lambda x: x.get_branch_hitrate() 253 sorter = lambda x: x.get_branch_hitrate()
217 elif sorting == 'hitrate': 254 elif sorting == 'hitrate':
218 sorter = lambda x: x.get_hitrate() 255 sorter = lambda x: x.get_hitrate()
219 elif sorting == 'coverage': 256 elif sorting == 'coverage':
220 sorter = lambda x: x.count 257 sorter = lambda x: x.count
221 elif sorting == 'name': 258 elif sorting == 'name':
222 sorter = lambda x: x.name.lower() 259 sorter = lambda x: x.name.lower()
223 260
224 print('%-40s %8s %6s %12s %18s %14s %8s %6s %12s %6s' % 261 print('%-40s %8s %6s %12s %18s %14s %8s %6s %12s %6s %s' %
225 ('HEURISTICS', 'BRANCHES', '(REL)', 262 ('HEURISTICS', 'BRANCHES', '(REL)',
226 'BR. HITRATE', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)', 263 'BR. HITRATE', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)',
227 'predict.def', '(REL)')) 264 'predict.def', '(REL)', 'HOT branches (>%d%%)' % hot_threshold))
228 for h in sorted(heuristics, key = sorter): 265 for h in sorted(heuristics, key = sorter):
229 h.print(branches_max, count_max, predict_def) 266 h.print(branches_max, count_max, predict_def)
230 267
231 def dump(self, sorting): 268 def dump(self, sorting):
232 heuristics = self.heuristics.values() 269 heuristics = self.heuristics.values()
264 choices = ['branches', 'branch-hitrate', 'hitrate', 'coverage', 'name'], 301 choices = ['branches', 'branch-hitrate', 'hitrate', 'coverage', 'name'],
265 default = 'branches') 302 default = 'branches')
266 parser.add_argument('-d', '--def-file', help = 'path to predict.def') 303 parser.add_argument('-d', '--def-file', help = 'path to predict.def')
267 parser.add_argument('-w', '--write-def-file', action = 'store_true', 304 parser.add_argument('-w', '--write-def-file', action = 'store_true',
268 help = 'Modify predict.def file in order to set new numbers') 305 help = 'Modify predict.def file in order to set new numbers')
306 parser.add_argument('-c', '--coverage-threshold', type = int,
307 help = 'Ignore edges that have percentage coverage >= coverage-threshold')
308 parser.add_argument('-v', '--verbose', action = 'store_true', help = 'Print verbose informations')
269 309
270 args = parser.parse_args() 310 args = parser.parse_args()
271 311
272 profile = Profile(args.dump_file) 312 profile = Profile(args.dump_file)
273 r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
274 loop_niter_str = ';; profile-based iteration count: ' 313 loop_niter_str = ';; profile-based iteration count: '
314
275 for l in open(args.dump_file): 315 for l in open(args.dump_file):
276 m = r.match(l) 316 if l.startswith(';;heuristics;'):
277 if m != None and m.group(3) == None: 317 parts = l.strip().split(';')
278 name = m.group(1) 318 assert len(parts) == 8
279 prediction = float(m.group(4)) 319 name = parts[3]
280 count = int(m.group(5)) 320 prediction = float(parts[6])
281 hits = int(m.group(6)) 321 count = int(parts[4])
322 hits = int(parts[5])
282 323
283 profile.add(name, prediction, count, hits) 324 profile.add(name, prediction, count, hits)
284 elif l.startswith(loop_niter_str): 325 elif l.startswith(loop_niter_str):
285 v = int(l[len(loop_niter_str):]) 326 v = int(l[len(loop_niter_str):])
286 profile.add_loop_niter(v) 327 profile.add_loop_niter(v)