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

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: refactor from comments 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 18 matching lines...) Expand all
43 44
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 iteritems(dispatches_table):
54 for destination, counter in counters_from_source.items(): 55 for destination, counter in iteritems(counters_from_source):
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 iteritems(dispatches_table):
63 for destination, counter in counters_from_source.items(): 64 for destination, counter in iteritems(counters_from_source):
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(dispatches_table):
79 top_bytecodes = [] 80 top_bytecodes = []
80 for bytecode, counters_from_bytecode in dispatches_table.items(): 81 for bytecode, counters_from_bytecode in iteritems(dispatches_table):
81 top_bytecodes.append((bytecode, sum(counters_from_bytecode.values()))) 82 top_bytecodes.append((bytecode, sum(itervalues(counters_from_bytecode))))
83
82 top_bytecodes.sort(key=lambda x: x[1], reverse=True) 84 top_bytecodes.sort(key=lambda x: x[1], reverse=True)
83 return top_bytecodes 85 return top_bytecodes
84 86
85 87
86 def print_top_bytecodes(dispatches_table): 88 def print_top_bytecodes(dispatches_table):
87 top_bytecodes = find_top_bytecodes(dispatches_table) 89 top_bytecodes = find_top_bytecodes(dispatches_table)
88 print "Top bytecodes:" 90 print "Top bytecodes:"
89 for bytecode, counter in top_bytecodes: 91 for bytecode, counter in top_bytecodes:
90 print "{:>12d}\t{}".format(counter, bytecode) 92 print "{:>12d}\t{}".format(counter, bytecode)
91 93
92 94
93 def find_top_dispatch_sources(dispatches_table, destination, top_count): 95 def find_top_dispatch_sources(dispatches_table, bytecode, top_count,
rmcilroy 2016/07/19 11:33:15 update name (find_top_dispatch_sources_and_destina
klaasb 2016/07/19 13:52:28 Done.
96 sort_source_relative):
97 relative_table = {}
98 for source, destinations in iteritems(dispatches_table):
99 total = float(sum(itervalues(destinations)))
100 relative_destinations = {}
101 relative_table[source] = relative_destinations
102 for destination, count in iteritems(destinations):
103 relative_destinations[destination] = (count, count / total)
104
94 def source_counters_generator(): 105 def source_counters_generator():
95 for source, table_row in dispatches_table.items(): 106 for source, table_row in iteritems(relative_table):
rmcilroy 2016/07/19 11:33:15 It seems a bit strange to have an inner function p
klaasb 2016/07/19 13:52:28 Done.
96 if destination in table_row: 107 if bytecode in table_row:
97 yield source, table_row[destination] 108 yield source, table_row[bytecode]
98 109
99 return heapq.nlargest(top_count, source_counters_generator(), 110 return (heapq.nlargest(top_count, source_counters_generator(),
100 key=lambda x: x[1]) 111 key=lambda x: x[1][1 if sort_source_relative else 0]),
112 heapq.nlargest(top_count, iteritems(relative_table[bytecode]),
113 key=lambda x: x[1][0]))
101 114
102 115
103 def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode, 116 def print_top_dispatch_sources_and_destinations(dispatches_table, bytecode,
104 top_count): 117 top_count, sort_relative):
105 top_sources = find_top_dispatch_sources(dispatches_table, bytecode, top_count) 118 top_sources, top_destinations = find_top_dispatch_sources(
106 top_destinations = heapq.nlargest(top_count, 119 dispatches_table, bytecode, top_count, sort_relative)
107 dispatches_table[bytecode].items(),
108 key=lambda x: x[1])
109
110 print "Top sources of dispatches to {}:".format(bytecode) 120 print "Top sources of dispatches to {}:".format(bytecode)
111 for source_name, counter in top_sources: 121 for source_name, (counter, ratio) in top_sources:
112 print "{:>12d}\t{}".format(counter, source_name) 122 print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, source_name)
113 123
114 print "\nTop destinations of dispatches from {}:".format(bytecode) 124 print "\nTop destinations of dispatches from {}:".format(bytecode)
115 for destination_name, counter in top_destinations: 125 for destination_name, (counter, ratio) in top_destinations:
116 print "{:>12d}\t{}".format(counter, destination_name) 126 print "{:>12d}\t{:>5.1f}%\t{}".format(counter, ratio * 100, destination_name )
117 127
118 128
119 def build_counters_matrix(dispatches_table): 129 def build_counters_matrix(dispatches_table):
120 labels = sorted(dispatches_table.keys()) 130 labels = sorted(dispatches_table.keys())
121 131
122 counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int) 132 counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int)
123 for from_index, from_name in enumerate(labels): 133 for from_index, from_name in enumerate(labels):
124 current_row = dispatches_table[from_name]; 134 current_row = dispatches_table[from_name];
125 for to_index, to_name in enumerate(labels): 135 for to_index, to_name in enumerate(labels):
126 counters_matrix[from_index, to_index] = current_row.get(to_name, 0) 136 counters_matrix[from_index, to_index] = current_row.get(to_name, 0)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 help="print top dispatch sources and destinations to the specified bytecode" 218 help="print top dispatch sources and destinations to the specified bytecode"
209 ) 219 )
210 command_line_parser.add_argument( 220 command_line_parser.add_argument(
211 "--output-filename", "-o", 221 "--output-filename", "-o",
212 metavar="<output filename>", 222 metavar="<output filename>",
213 default="v8.ignition_dispatches_table.svg", 223 default="v8.ignition_dispatches_table.svg",
214 help=("file to save the plot file to. File type is deduced from the " 224 help=("file to save the plot file to. File type is deduced from the "
215 "extension. PDF, SVG, PNG supported") 225 "extension. PDF, SVG, PNG supported")
216 ) 226 )
217 command_line_parser.add_argument( 227 command_line_parser.add_argument(
228 "--sort-sources-relative", "-r",
229 action="store_true",
230 help=("print top sources in order to how often they dispatch to the "
231 "specified bytecode, only applied when using -f")
232 )
233 command_line_parser.add_argument(
218 "input_filename", 234 "input_filename",
219 metavar="<input filename>", 235 metavar="<input filename>",
220 default="v8.ignition_dispatches_table.json", 236 default="v8.ignition_dispatches_table.json",
221 nargs='?', 237 nargs='?',
222 help="Ignition counters JSON file" 238 help="Ignition counters JSON file"
223 ) 239 )
224 240
225 return command_line_parser.parse_args() 241 return command_line_parser.parse_args()
226 242
227 243
244 def itervalues(d):
245 return d.values() if sys.version_info[0] > 2 else d.itervalues()
246
247
248 def iteritems(d):
249 return d.items() if sys.version_info[0] > 2 else d.iteritems()
250
251
228 def main(): 252 def main():
229 program_options = parse_command_line() 253 program_options = parse_command_line()
230 254
231 with open(program_options.input_filename) as stream: 255 with open(program_options.input_filename) as stream:
232 dispatches_table = json.load(stream) 256 dispatches_table = json.load(stream)
233 257
234 warn_if_counter_may_have_saturated(dispatches_table) 258 warn_if_counter_may_have_saturated(dispatches_table)
235 259
236 if program_options.plot: 260 if program_options.plot:
237 figure, axis = pyplot.subplots() 261 figure, axis = pyplot.subplots()
238 plot_dispatches_table(dispatches_table, figure, axis) 262 plot_dispatches_table(dispatches_table, figure, axis)
239 263
240 if program_options.interactive: 264 if program_options.interactive:
241 pyplot.show() 265 pyplot.show()
242 else: 266 else:
243 figure.set_size_inches(program_options.plot_size, 267 figure.set_size_inches(program_options.plot_size,
244 program_options.plot_size) 268 program_options.plot_size)
245 pyplot.savefig(program_options.output_filename) 269 pyplot.savefig(program_options.output_filename)
246 elif program_options.top_bytecode_dispatch_pairs: 270 elif program_options.top_bytecode_dispatch_pairs:
247 print_top_bytecode_dispatch_pairs( 271 print_top_bytecode_dispatch_pairs(
248 dispatches_table, program_options.top_entries_count) 272 dispatches_table, program_options.top_entries_count)
249 elif program_options.top_dispatches_for_bytecode: 273 elif program_options.top_dispatches_for_bytecode:
250 print_top_dispatch_sources_and_destinations( 274 print_top_dispatch_sources_and_destinations(
251 dispatches_table, program_options.top_dispatches_for_bytecode, 275 dispatches_table, program_options.top_dispatches_for_bytecode,
252 program_options.top_entries_count) 276 program_options.top_entries_count, program_options.sort_sources_relative)
253 else: 277 else:
254 print_top_bytecodes(dispatches_table) 278 print_top_bytecodes(dispatches_table)
255 279
256 280
257 if __name__ == "__main__": 281 if __name__ == "__main__":
258 main() 282 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