[turbolizer] Improved display of perf profiling information.
All events recorded are shown in separate columns simulatneously, using rectangles with heatmap-style colouring. Hovering over the shapes gives the event name, count, and percentage. BUG= Review-Url: https://codereview.chromium.org/2228553004 Cr-Commit-Position: refs/heads/master@{#39408}
This commit is contained in:
parent
cce56a3f47
commit
4a64e9497b
@ -20,5 +20,11 @@ var DISASSEMBLY_COLLAPSE_ID = 'disassembly-shrink';
|
||||
var DISASSEMBLY_EXPAND_ID = 'disassembly-expand';
|
||||
var COLLAPSE_PANE_BUTTON_VISIBLE = 'button-input';
|
||||
var COLLAPSE_PANE_BUTTON_INVISIBLE = 'button-input-invisible';
|
||||
var PROF_HIGH = 5;
|
||||
var PROF_MED = 0.5;
|
||||
var UNICODE_BLOCK = '▋';
|
||||
var PROF_COLS = [
|
||||
{ perc: 0, col: { r: 255, g: 255, b: 255 } },
|
||||
{ perc: 0.5, col: { r: 255, g: 255, b: 128 } },
|
||||
{ perc: 5, col: { r: 255, g: 128, b: 0 } },
|
||||
{ perc: 15, col: { r: 255, g: 0, b: 0 } },
|
||||
{ perc: 100, col: { r: 0, g: 0, b: 0 } }
|
||||
];
|
||||
|
@ -159,6 +159,7 @@ class DisassemblyView extends TextView {
|
||||
view.pos_start = -1;
|
||||
view.addr_event_counts = null;
|
||||
view.total_event_counts = null;
|
||||
view.max_event_counts = null;
|
||||
view.pos_lines = new Array();
|
||||
// Comment lines for line 0 include sourcePosition already, only need to
|
||||
// add sourcePosition for lines > 0.
|
||||
@ -181,15 +182,18 @@ class DisassemblyView extends TextView {
|
||||
view.addr_event_counts = eventCounts;
|
||||
|
||||
view.total_event_counts = {};
|
||||
for (var ev_name in view.addr_event_counts) {
|
||||
view.max_event_counts = {};
|
||||
for (let ev_name in view.addr_event_counts) {
|
||||
let keys = Object.keys(view.addr_event_counts[ev_name]);
|
||||
let values = keys.map(key => view.addr_event_counts[ev_name][key]);
|
||||
view.total_event_counts[ev_name] = values.reduce((a, b) => a + b);
|
||||
view.max_event_counts[ev_name] = values.reduce((a, b) => Math.max(a, b));
|
||||
}
|
||||
}
|
||||
else {
|
||||
view.addr_event_counts = null;
|
||||
view.total_event_counts = null;
|
||||
view.max_event_counts = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,6 +202,11 @@ class DisassemblyView extends TextView {
|
||||
return num.toFixed(3).replace(/\.?0+$/, "") + "%";
|
||||
}
|
||||
|
||||
// Interpolate between the given start and end values by a fraction of val/max.
|
||||
interpolate(val, max, start, end) {
|
||||
return start + (end - start) * (val / max);
|
||||
}
|
||||
|
||||
processLine(line) {
|
||||
let view = this;
|
||||
let func = function(match, p1, p2, p3) {
|
||||
@ -214,30 +223,49 @@ class DisassemblyView extends TextView {
|
||||
|
||||
// Add profiling data per instruction if available.
|
||||
if (view.total_event_counts) {
|
||||
let event_selector = document.getElementById('event-selector');
|
||||
if (event_selector.length !== 0) {
|
||||
let event = event_selector.value;
|
||||
let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line);
|
||||
if (matches) {
|
||||
let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line);
|
||||
if (matches) {
|
||||
let newFragments = [];
|
||||
for (let event in view.addr_event_counts) {
|
||||
let count = view.addr_event_counts[event][matches[1]];
|
||||
let str = "";
|
||||
let css_cls = undefined;
|
||||
let str = " ";
|
||||
let css_cls = "prof";
|
||||
if(count !== undefined) {
|
||||
let perc = count / view.total_event_counts[event] * 100;
|
||||
|
||||
str = "(" + view.humanize(perc) + ") ";
|
||||
let col = { r: 255, g: 255, b: 255 };
|
||||
for (let i = 0; i < PROF_COLS.length; i++) {
|
||||
if (perc === PROF_COLS[i].perc) {
|
||||
col = PROF_COLS[i].col;
|
||||
break;
|
||||
}
|
||||
else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) {
|
||||
let col1 = PROF_COLS[i].col;
|
||||
let col2 = PROF_COLS[i + 1].col;
|
||||
|
||||
css_cls = "prof-low";
|
||||
if(perc > PROF_HIGH)
|
||||
css_cls = "prof-high";
|
||||
else if(perc > PROF_MED)
|
||||
css_cls = "prof-med";
|
||||
let val = perc - PROF_COLS[i].perc;
|
||||
let max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc;
|
||||
|
||||
col.r = Math.round(view.interpolate(val, max, col1.r, col2.r));
|
||||
col.g = Math.round(view.interpolate(val, max, col1.g, col2.g));
|
||||
col.b = Math.round(view.interpolate(val, max, col1.b, col2.b));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str = UNICODE_BLOCK;
|
||||
|
||||
let fragment = view.createFragment(str, css_cls);
|
||||
fragment.title = event + ": " + view.humanize(perc) + " (" + count + ")";
|
||||
fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b + ")";
|
||||
|
||||
newFragments.push(fragment);
|
||||
}
|
||||
// Pad extra spaces to keep alignment for all instructions.
|
||||
str = (" ".repeat(10) + str).slice(-10);
|
||||
else
|
||||
newFragments.push(view.createFragment(str, css_cls));
|
||||
|
||||
fragments.splice(0, 0, view.createFragment(str, css_cls));
|
||||
}
|
||||
fragments = newFragments.concat(fragments);
|
||||
}
|
||||
}
|
||||
return fragments;
|
||||
|
@ -54,12 +54,9 @@
|
||||
</text></svg></div>
|
||||
</div>
|
||||
<div id="right">
|
||||
<span id="disassembly-toolbox">
|
||||
<select id="event-selector"></select>
|
||||
</span>
|
||||
<div id='disassembly'>
|
||||
<pre id='disassembly-text-pre' class='prettyprint prettyprinted'>
|
||||
<ul id='disassembly-list' class='nolinenums noindent'>
|
||||
<ul id='disassembly-list' class='nolinenums noindent'>
|
||||
</ul>
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -120,7 +120,7 @@ class TextView extends View {
|
||||
if (style != undefined) {
|
||||
span.classList.add(style);
|
||||
}
|
||||
span.innerText = text;
|
||||
span.innerHTML = text;
|
||||
return span;
|
||||
}
|
||||
|
||||
|
@ -326,16 +326,8 @@ span.linkable-text:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.prof-low {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.prof-med {
|
||||
color: #080;
|
||||
}
|
||||
|
||||
.prof-high {
|
||||
color: #800;
|
||||
.prof {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
tspan {
|
||||
|
@ -188,13 +188,6 @@ document.onload = (function(d3){
|
||||
}
|
||||
}
|
||||
|
||||
var eventMenu = document.getElementById('event-selector');
|
||||
eventMenu.innerHTML = '';
|
||||
for (var event in jsonObj.eventCounts) {
|
||||
var optionElement = document.createElement("option");
|
||||
optionElement.text = event;
|
||||
eventMenu.add(optionElement, null);
|
||||
}
|
||||
disassemblyView.initializePerfProfile(jsonObj.eventCounts);
|
||||
disassemblyView.show(disassemblyPhase.data, null);
|
||||
|
||||
@ -216,10 +209,6 @@ document.onload = (function(d3){
|
||||
displayPhase(jsonObj.phases[selectMenu.selectedIndex]);
|
||||
}
|
||||
|
||||
eventMenu.onchange = function(item) {
|
||||
disassemblyView.show(disassemblyView.data, null);
|
||||
}
|
||||
|
||||
fitPanesToParents();
|
||||
|
||||
d3.select("#search-input").attr("value", window.sessionStorage.getItem("lastSearch") || "");
|
||||
|
Loading…
Reference in New Issue
Block a user