Mercurial > hg > CbC > CbC_gcc
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) |