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

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

Issue 1869423002: [Interpreter] Add visualization tool for Ignition dispatch counters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Extracting code to test, adding unit tests. Created 4 years, 8 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
OLDNEW
(Empty)
1 #! /usr/bin/python
2 #
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
5 # found in the LICENSE file.
6 #
7
8 import argparse
9 import heapq
10 import json
11 from matplotlib import colors
12 from matplotlib import pyplot
13 import numpy
14 import struct
15
16
17 __DESCRIPTION = """
18 Process v8.ignition_dispatches_counters.json and list top counters,
19 or plot a dispatch heatmap.
20 """
21
22
23 __HELP_EPILOGUE = """
24 examples:
25 # Print the top 10 counters, reading from default filename
26 # v8.ignition_dispatches_counters.json (default mode)
27 $ tools/ignition/bytecode_dispatches_report.py
28
29 # Print the top 15 counters reading from data.json
30 $ tools/ignition/bytecode_dispatches_report.py -t 15 data.json
31
32 # Save heatmap to default filename v8.ignition_dispatches_counters.svg
33 $ tools/ignition/bytecode_dispatches_report.py -p
34
35 # Save heatmap to filename data.svg
36 $ tools/ignition/bytecode_dispatches_report.py -p -o data.svg
37
38 # Open the heatmap in an interactive viewer
39 $ tools/ignition/bytecode_dispatches_report.py -p -i
40 """
41
42 __COUNTER_BITS = struct.calcsize("P") * 8 # Size in bits of a pointer
43 __COUNTER_MAX = 2**__COUNTER_BITS - 1
44
45
46 def warn_if_counter_may_have_saturated(dispatches_table):
47 for source, counters_from_source in dispatches_table.items():
48 for destination, counter in counters_from_source.items():
49 if counter == __COUNTER_MAX:
50 print "WARNING: {} -> {} may have saturated.".format(source,
51 destination)
52
53
54 def find_top_counters(dispatches_table, top_count):
55 def flattened_counters_generator():
56 for source, counters_from_source in dispatches_table.items():
57 for destination, counter in counters_from_source.items():
58 yield source, destination, counter
59
60 return heapq.nlargest(top_count, flattened_counters_generator(),
61 key=lambda x: x[2])
62
63
64 def print_top_counters(dispatches_table, top_count):
65 top_counters = find_top_counters(dispatches_table, top_count)
66 print "Top {} dispatch counters:".format(top_count)
67 for source, destination, counter in top_counters:
68 print "{:>12d}\t{} -> {}".format(counter, source, destination)
69
70
71 def build_counters_matrix(dispatches_table):
72 labels = sorted(dispatches_table.keys())
73
74 counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int)
75 for from_index, from_name in enumerate(labels):
76 current_row = dispatches_table[from_name];
77 for to_index, to_name in enumerate(labels):
78 counters_matrix[from_index, to_index] = current_row.get(to_name, 0)
79
80 # Reverse y axis for a nicer appearance
81 xlabels = labels
82 ylabels = list(reversed(xlabels))
83 counters_matrix = numpy.flipud(counters_matrix)
84
85 return counters_matrix, xlabels, ylabels
86
87
88 def plot_dispatches_table(dispatches_table, figure, axis):
89 counters_matrix, xlabels, ylabels = build_counters_matrix(dispatches_table)
90
91 image = axis.pcolor(
92 counters_matrix,
93 cmap='jet',
94 norm=colors.LogNorm(),
95 edgecolor='grey',
96 linestyle='dotted',
97 linewidth=0.5
98 )
99
100 axis.xaxis.set(
101 ticks=numpy.arange(0.5, len(xlabels)),
102 label="From bytecode handler"
103 )
104 axis.xaxis.tick_top()
105 axis.set_xlim(0, len(xlabels))
106 axis.set_xticklabels(xlabels, rotation='vertical')
107
108 axis.yaxis.set(
109 ticks=numpy.arange(0.5, len(ylabels)),
110 label="To bytecode handler",
111 ticklabels=ylabels
112 )
113 axis.set_ylim(0, len(ylabels))
114
115 figure.colorbar(
116 image,
117 ax=axis,
118 fraction=0.01,
119 pad=0.01
120 )
121
122
123 def parse_command_line():
124 command_line_parser = argparse.ArgumentParser(
125 formatter_class=argparse.RawDescriptionHelpFormatter,
126 description=__DESCRIPTION,
127 epilog=__HELP_EPILOGUE
128 )
129 command_line_parser.add_argument(
130 "--plot_size", "-s",
131 metavar="N",
132 default=30,
133 help="shorter side, in inches, of the output plot (default 30)"
134 )
135 command_line_parser.add_argument(
136 "--plot", "-p",
137 action="store_true",
138 help="plot dispatches table heatmap"
139 )
140 command_line_parser.add_argument(
141 "--interactive", "-i",
142 action="store_true",
143 help="open an interactive viewer, rather than writing to file"
144 )
145 command_line_parser.add_argument(
146 "--top_count", "-t",
147 metavar="N",
148 type=int,
149 default=10,
150 help="print the top N counters (default 10)"
151 )
152 command_line_parser.add_argument(
153 "--output_filename", "-o",
154 metavar="<output filename>",
155 default="v8.ignition_dispatches_table.svg",
156 help=("file to save the plot file to. File type is deduced from the "
157 "extension. PDF, SVG, PNG supported")
158 )
159 command_line_parser.add_argument(
160 "input_filename",
161 metavar="<input filename>",
162 default="v8.ignition_dispatches_table.json",
163 nargs='?',
164 help="Ignition counters JSON file"
165 )
166
167 return command_line_parser.parse_args()
168
169
170 def main():
171 program_options = parse_command_line()
172
173 with open(program_options.input_filename) as stream:
174 dispatches_table = json.load(stream)
175
176 warn_if_counter_may_have_saturated(dispatches_table)
177
178 if program_options.plot:
179 figure, axis = pyplot.subplots()
180 plot_dispatches_table(dispatches_table, figure, axis)
181
182 if program_options.interactive:
183 pyplot.show()
184 else:
185 figure.set_size_inches(program_options.plot_size,
186 program_options.plot_size)
187 pyplot.savefig(program_options.output_filename)
188 else:
189 print_top_counters(dispatches_table, program_options.top_count)
190
191
192 if __name__ == "__main__":
193 main()
OLDNEW
« no previous file with comments | « no previous file | tools/ignition/bytecode_dispatches_report_test.py » ('j') | tools/ignition/bytecode_dispatches_report_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698