Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1729)

Side by Side Diff: tools/ignition/bytecode_dispatches_report.py

Issue 2159683003: [interpreter] Add relative numbers to dispatch report (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/ignition/bytecode_dispatches_report_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #! /usr/bin/python 1 #! /usr/bin/python
2 # 2 #
3 # Copyright 2016 the V8 project authors. All rights reserved. 3 # Copyright 2016 the V8 project authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 # 6 #
7 7
8 import argparse 8 import argparse
9 import heapq 9 import heapq
10 import json 10 import json
11 from matplotlib import colors 11 from matplotlib import colors
12 from matplotlib import pyplot 12 from matplotlib import pyplot
13 import numpy 13 import numpy
14 import struct 14 import struct
15 import sys
15 16
16 17
17 __DESCRIPTION = """ 18 __DESCRIPTION = """
18 Process v8.ignition_dispatches_counters.json and list top counters, 19 Process v8.ignition_dispatches_counters.json and list top counters,
19 or plot a dispatch heatmap. 20 or plot a dispatch heatmap.
20 21
21 Please note that those handlers that may not or will never dispatch 22 Please note that those handlers that may not or will never dispatch
22 (e.g. Return or Throw) do not show up in the results. 23 (e.g. Return or Throw) do not show up in the results.
23 """ 24 """
24 25
(...skipping 19 matching lines...) Expand all
44 # Display the top 5 sources and destinations of dispatches to/from LdaZero 45 # Display the top 5 sources and destinations of dispatches to/from LdaZero
45 $ tools/ignition/bytecode_dispatches_report.py -f LdaZero -n 5 46 $ tools/ignition/bytecode_dispatches_report.py -f LdaZero -n 5
46 """ 47 """
47 48
48 __COUNTER_BITS = struct.calcsize("P") * 8 # Size in bits of a pointer 49 __COUNTER_BITS = struct.calcsize("P") * 8 # Size in bits of a pointer
49 __COUNTER_MAX = 2**__COUNTER_BITS - 1 50 __COUNTER_MAX = 2**__COUNTER_BITS - 1
50 51
51 52
52 def warn_if_counter_may_have_saturated(dispatches_table): 53 def warn_if_counter_may_have_saturated(dispatches_table):
53 for source, counters_from_source in dispatches_table.items(): 54 for source, counters_from_source in dispatches_table.items():
54 for destination, counter in counters_from_source.items(): 55 for destination, (counter, ratio) in counters_from_source.items():
55 if counter == __COUNTER_MAX: 56 if counter == __COUNTER_MAX:
56 print "WARNING: {} -> {} may have saturated.".format(source, 57 print "WARNING: {} -> {} may have saturated.".format(source,
57 destination) 58 destination)
58 59
59 60
60 def find_top_bytecode_dispatch_pairs(dispatches_table, top_count): 61 def find_top_bytecode_dispatch_pairs(dispatches_table, top_count):
61 def flattened_counters_generator(): 62 def flattened_counters_generator():
62 for source, counters_from_source in dispatches_table.items(): 63 for source, counters_from_source in dispatches_table.items():
63 for destination, counter in counters_from_source.items(): 64 for destination, (counter, ratio) in counters_from_source.items():
64 yield source, destination, counter 65 yield source, destination, counter
65 66
66 return heapq.nlargest(top_count, flattened_counters_generator(), 67 return heapq.nlargest(top_count, flattened_counters_generator(),
67 key=lambda x: x[2]) 68 key=lambda x: x[2])
68 69
69 70
70 def print_top_bytecode_dispatch_pairs(dispatches_table, top_count): 71 def print_top_bytecode_dispatch_pairs(dispatches_table, top_count):
71 top_bytecode_dispatch_pairs = ( 72 top_bytecode_dispatch_pairs = (
72 find_top_bytecode_dispatch_pairs(dispatches_table, top_count)) 73 find_top_bytecode_dispatch_pairs(dispatches_table, top_count))
73 print "Top {} bytecode dispatch pairs:".format(top_count) 74 print "Top {} bytecode dispatch pairs:".format(top_count)
74 for source, destination, counter in top_bytecode_dispatch_pairs: 75 for source, destination, counter in top_bytecode_dispatch_pairs:
75 print "{:>12d}\t{} -> {}".format(counter, source, destination) 76 print "{:>12d}\t{} -> {}".format(counter, source, destination)
76 77
77 78
78 def find_top_bytecodes(dispatches_table): 79 def find_top_bytecodes(dispatch_totals):
79 top_bytecodes = [] 80 top_bytecodes = list(iteritems(dispatch_totals))
80 for bytecode, counters_from_bytecode in dispatches_table.items():
81 top_bytecodes.append((bytecode, sum(counters_from_bytecode.values())))
82 top_bytecodes.sort(key=lambda x: x[1], reverse=True) 81 top_bytecodes.sort(key=lambda x: x[1], reverse=True)
83 return top_bytecodes 82 return top_bytecodes
84 83
85 84
86 def print_top_bytecodes(dispatches_table): 85 def print_top_bytecodes(dispatch_totals):
87 top_bytecodes = find_top_bytecodes(dispatches_table) 86 top_bytecodes = find_top_bytecodes(dispatch_totals)
88 print "Top bytecodes:" 87 print "Top bytecodes:"
89 for bytecode, counter in top_bytecodes: 88 for bytecode, counter in top_bytecodes:
90 print "{:>12d}\t{}".format(counter, bytecode) 89 print "{:>12d}\t{}".format(counter, bytecode)
91 90
92 91
93 def find_top_dispatch_sources(dispatches_table, destination, top_count): 92 def find_top_dispatch_sources(dispatches_table, destination, top_count,
93 sort_source_relative):
94 def source_counters_generator(): 94 def source_counters_generator():
95 for source, table_row in dispatches_table.items(): 95 for source, table_row in dispatches_table.items():
96 if destination in table_row: 96 if destination in table_row:
97 yield source, table_row[destination] 97 yield source, table_row[destination]
98 98
99 return heapq.nlargest(top_count, source_counters_generator(), 99 return heapq.nlargest(top_count, source_counters_generator(),
100 key=lambda x: x[1]) 100 key=lambda x: x[1][1 if sort_source_relative else 0])
101 101
102 102
103 def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode, 103 def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode,
104 top_count): 104 top_count, sort_relative):
105 top_sources = find_top_dispatch_sources(dispatches_table, bytecode, top_count) 105 top_sources = find_top_dispatch_sources(dispatches_table, bytecode,
106 top_count, sort_relative)
106 top_destinations = heapq.nlargest(top_count, 107 top_destinations = heapq.nlargest(top_count,
107 dispatches_table[bytecode].items(), 108 dispatches_table[bytecode].items(),
108 key=lambda x: x[1]) 109 key=lambda x: x[1][0])
109 110
110 print "Top sources of dispatches to {}:".format(bytecode) 111 print "Top sources of dispatches to {}:".format(bytecode)
111 for source_name, counter in top_sources: 112 for source_name, (counter, ratio) in top_sources:
112 print "{:>12d}\t{}".format(counter, source_name) 113 print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, source_name)
113 114
114 print "\nTop destinations of dispatches from {}:".format(bytecode) 115 print "\nTop destinations of dispatches from {}:".format(bytecode)
115 for destination_name, counter in top_destinations: 116 for destination_name, (counter, ratio) in top_destinations:
116 print "{:>12d}\t{}".format(counter, destination_name) 117 print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, destination_name )
117 118
118 119
119 def build_counters_matrix(dispatches_table): 120 def build_counters_matrix(dispatches_table):
120 labels = sorted(dispatches_table.keys()) 121 labels = sorted(dispatches_table.keys())
121 122
122 counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int) 123 counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int)
123 for from_index, from_name in enumerate(labels): 124 for from_index, from_name in enumerate(labels):
124 current_row = dispatches_table[from_name]; 125 current_row = dispatches_table[from_name];
125 for to_index, to_name in enumerate(labels): 126 for to_index, to_name in enumerate(labels):
126 counters_matrix[from_index, to_index] = current_row.get(to_name, 0) 127 counters_matrix[from_index, to_index] = current_row.get(to_name, (0, 0))[0 ]
127 128
128 # Reverse y axis for a nicer appearance 129 # Reverse y axis for a nicer appearance
129 xlabels = labels 130 xlabels = labels
130 ylabels = list(reversed(xlabels)) 131 ylabels = list(reversed(xlabels))
131 counters_matrix = numpy.flipud(counters_matrix) 132 counters_matrix = numpy.flipud(counters_matrix)
132 133
133 return counters_matrix, xlabels, ylabels 134 return counters_matrix, xlabels, ylabels
134 135
135 136
136 def plot_dispatches_table(dispatches_table, figure, axis): 137 def plot_dispatches_table(dispatches_table, figure, axis):
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 help="print top dispatch sources and destinations to the specified bytecode" 209 help="print top dispatch sources and destinations to the specified bytecode"
209 ) 210 )
210 command_line_parser.add_argument( 211 command_line_parser.add_argument(
211 "--output-filename", "-o", 212 "--output-filename", "-o",
212 metavar="<output filename>", 213 metavar="<output filename>",
213 default="v8.ignition_dispatches_table.svg", 214 default="v8.ignition_dispatches_table.svg",
214 help=("file to save the plot file to. File type is deduced from the " 215 help=("file to save the plot file to. File type is deduced from the "
215 "extension. PDF, SVG, PNG supported") 216 "extension. PDF, SVG, PNG supported")
216 ) 217 )
217 command_line_parser.add_argument( 218 command_line_parser.add_argument(
219 "--sort-sources-relative", "-r",
220 action="store_true",
221 help=("print top sources in order to how often they dispatch to the "
222 "speficied bytecode")
rmcilroy 2016/07/19 09:23:08 fix typo
klaasb 2016/07/19 10:24:27 Done.
223 )
224 command_line_parser.add_argument(
218 "input_filename", 225 "input_filename",
219 metavar="<input filename>", 226 metavar="<input filename>",
220 default="v8.ignition_dispatches_table.json", 227 default="v8.ignition_dispatches_table.json",
221 nargs='?', 228 nargs='?',
222 help="Ignition counters JSON file" 229 help="Ignition counters JSON file"
223 ) 230 )
224 231
225 return command_line_parser.parse_args() 232 return command_line_parser.parse_args()
226 233
227 234
235 def itervalues(d):
236 return d.values() if sys.version_info[0] > 2 else d.itervalues()
237
238
239 def iteritems(d):
240 return d.items() if sys.version_info[0] > 2 else d.iteritems()
241
242
228 def main(): 243 def main():
229 program_options = parse_command_line() 244 program_options = parse_command_line()
230 245
231 with open(program_options.input_filename) as stream: 246 with open(program_options.input_filename) as stream:
232 dispatches_table = json.load(stream) 247 dispatches_table = json.load(stream)
233 248
249 dispatch_totals = {}
250 for source, destinations in dispatches_table.items():
251 total = sum(itervalues(destinations))
252 dispatch_totals[source] = total
253 total = float(total)
254 for destination, count in destinations.iteritems():
255 destinations[destination] = (count, count / total)
rmcilroy 2016/07/19 09:23:08 I think it would be better to do this as a process
klaasb 2016/07/19 10:24:27 Done.
256
234 warn_if_counter_may_have_saturated(dispatches_table) 257 warn_if_counter_may_have_saturated(dispatches_table)
235 258
236 if program_options.plot: 259 if program_options.plot:
237 figure, axis = pyplot.subplots() 260 figure, axis = pyplot.subplots()
238 plot_dispatches_table(dispatches_table, figure, axis) 261 plot_dispatches_table(dispatches_table, figure, axis)
239 262
240 if program_options.interactive: 263 if program_options.interactive:
241 pyplot.show() 264 pyplot.show()
242 else: 265 else:
243 figure.set_size_inches(program_options.plot_size, 266 figure.set_size_inches(program_options.plot_size,
244 program_options.plot_size) 267 program_options.plot_size)
245 pyplot.savefig(program_options.output_filename) 268 pyplot.savefig(program_options.output_filename)
246 elif program_options.top_bytecode_dispatch_pairs: 269 elif program_options.top_bytecode_dispatch_pairs:
247 print_top_bytecode_dispatch_pairs( 270 print_top_bytecode_dispatch_pairs(
248 dispatches_table, program_options.top_entries_count) 271 dispatches_table, program_options.top_entries_count)
249 elif program_options.top_dispatches_for_bytecode: 272 elif program_options.top_dispatches_for_bytecode:
250 print_top_dispatch_sources_and_destinations( 273 print_top_dispatch_sources_and_destinations(
251 dispatches_table, program_options.top_dispatches_for_bytecode, 274 dispatches_table, program_options.top_dispatches_for_bytecode,
252 program_options.top_entries_count) 275 program_options.top_entries_count, program_options.sort_sources_relative)
253 else: 276 else:
254 print_top_bytecodes(dispatches_table) 277 print_top_bytecodes(dispatch_totals)
255 278
256 279
257 if __name__ == "__main__": 280 if __name__ == "__main__":
258 main() 281 main()
OLDNEW
« no previous file with comments | « no previous file | tools/ignition/bytecode_dispatches_report_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698