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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: tools/ignition/bytecode_dispatches_report.py
diff --git a/tools/ignition/bytecode_dispatches_report.py b/tools/ignition/bytecode_dispatches_report.py
new file mode 100755
index 0000000000000000000000000000000000000000..2c04bef600e0336e9cb84f21d928b20eb3eb61eb
--- /dev/null
+++ b/tools/ignition/bytecode_dispatches_report.py
@@ -0,0 +1,193 @@
+#! /usr/bin/python
+#
+# Copyright 2016 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+
+import argparse
+import heapq
+import json
+from matplotlib import colors
+from matplotlib import pyplot
+import numpy
+import struct
+
+
+__DESCRIPTION = """
+Process v8.ignition_dispatches_counters.json and list top counters,
+or plot a dispatch heatmap.
+"""
+
+
+__HELP_EPILOGUE = """
+examples:
+ # Print the top 10 counters, reading from default filename
+ # v8.ignition_dispatches_counters.json (default mode)
+ $ tools/ignition/bytecode_dispatches_report.py
+
+ # Print the top 15 counters reading from data.json
+ $ tools/ignition/bytecode_dispatches_report.py -t 15 data.json
+
+ # Save heatmap to default filename v8.ignition_dispatches_counters.svg
+ $ tools/ignition/bytecode_dispatches_report.py -p
+
+ # Save heatmap to filename data.svg
+ $ tools/ignition/bytecode_dispatches_report.py -p -o data.svg
+
+ # Open the heatmap in an interactive viewer
+ $ tools/ignition/bytecode_dispatches_report.py -p -i
+"""
+
+__COUNTER_BITS = struct.calcsize("P") * 8 # Size in bits of a pointer
+__COUNTER_MAX = 2**__COUNTER_BITS - 1
+
+
+def warn_if_counter_may_have_saturated(dispatches_table):
+ for source, counters_from_source in dispatches_table.items():
+ for destination, counter in counters_from_source.items():
+ if counter == __COUNTER_MAX:
+ print "WARNING: {} -> {} may have saturated.".format(source,
+ destination)
+
+
+def find_top_counters(dispatches_table, top_count):
+ def flattened_counters_generator():
+ for source, counters_from_source in dispatches_table.items():
+ for destination, counter in counters_from_source.items():
+ yield source, destination, counter
+
+ return heapq.nlargest(top_count, flattened_counters_generator(),
+ key=lambda x: x[2])
+
+
+def print_top_counters(dispatches_table, top_count):
+ top_counters = find_top_counters(dispatches_table, top_count)
+ print "Top {} dispatch counters:".format(top_count)
+ for source, destination, counter in top_counters:
+ print "{:>12d}\t{} -> {}".format(counter, source, destination)
+
+
+def build_counters_matrix(dispatches_table):
+ labels = sorted(dispatches_table.keys())
+
+ counters_matrix = numpy.empty([len(labels), len(labels)], dtype=int)
+ for from_index, from_name in enumerate(labels):
+ current_row = dispatches_table[from_name];
+ for to_index, to_name in enumerate(labels):
+ counters_matrix[from_index, to_index] = current_row.get(to_name, 0)
+
+ # Reverse y axis for a nicer appearance
+ xlabels = labels
+ ylabels = list(reversed(xlabels))
+ counters_matrix = numpy.flipud(counters_matrix)
+
+ return counters_matrix, xlabels, ylabels
+
+
+def plot_dispatches_table(dispatches_table, figure, axis):
+ counters_matrix, xlabels, ylabels = build_counters_matrix(dispatches_table)
+
+ image = axis.pcolor(
+ counters_matrix,
+ cmap='jet',
+ norm=colors.LogNorm(),
+ edgecolor='grey',
+ linestyle='dotted',
+ linewidth=0.5
+ )
+
+ axis.xaxis.set(
+ ticks=numpy.arange(0.5, len(xlabels)),
+ label="From bytecode handler"
+ )
+ axis.xaxis.tick_top()
+ axis.set_xlim(0, len(xlabels))
+ axis.set_xticklabels(xlabels, rotation='vertical')
+
+ axis.yaxis.set(
+ ticks=numpy.arange(0.5, len(ylabels)),
+ label="To bytecode handler",
+ ticklabels=ylabels
+ )
+ axis.set_ylim(0, len(ylabels))
+
+ figure.colorbar(
+ image,
+ ax=axis,
+ fraction=0.01,
+ pad=0.01
+ )
+
+
+def parse_command_line():
+ command_line_parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=__DESCRIPTION,
+ epilog=__HELP_EPILOGUE
+ )
+ command_line_parser.add_argument(
+ "--plot_size", "-s",
+ metavar="N",
+ default=30,
+ help="shorter side, in inches, of the output plot (default 30)"
+ )
+ command_line_parser.add_argument(
+ "--plot", "-p",
+ action="store_true",
+ help="plot dispatches table heatmap"
+ )
+ command_line_parser.add_argument(
+ "--interactive", "-i",
+ action="store_true",
+ help="open an interactive viewer, rather than writing to file"
+ )
+ command_line_parser.add_argument(
+ "--top_count", "-t",
+ metavar="N",
+ type=int,
+ default=10,
+ help="print the top N counters (default 10)"
+ )
+ command_line_parser.add_argument(
+ "--output_filename", "-o",
+ metavar="<output filename>",
+ default="v8.ignition_dispatches_table.svg",
+ help=("file to save the plot file to. File type is deduced from the "
+ "extension. PDF, SVG, PNG supported")
+ )
+ command_line_parser.add_argument(
+ "input_filename",
+ metavar="<input filename>",
+ default="v8.ignition_dispatches_table.json",
+ nargs='?',
+ help="Ignition counters JSON file"
+ )
+
+ return command_line_parser.parse_args()
+
+
+def main():
+ program_options = parse_command_line()
+
+ with open(program_options.input_filename) as stream:
+ dispatches_table = json.load(stream)
+
+ warn_if_counter_may_have_saturated(dispatches_table)
+
+ if program_options.plot:
+ figure, axis = pyplot.subplots()
+ plot_dispatches_table(dispatches_table, figure, axis)
+
+ if program_options.interactive:
+ pyplot.show()
+ else:
+ figure.set_size_inches(program_options.plot_size,
+ program_options.plot_size)
+ pyplot.savefig(program_options.output_filename)
+ else:
+ print_top_counters(dispatches_table, program_options.top_count)
+
+
+if __name__ == "__main__":
+ main()
« 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