viz: use content headers for profiler (#13383)

This commit is contained in:
qazal
2025-11-20 23:33:16 +08:00
committed by GitHub
parent 0b0ea4981c
commit ebcdf68bab
2 changed files with 10 additions and 6 deletions

View File

@@ -208,7 +208,7 @@ async function renderProfiler(path, unit) {
// support non realtime x axis units
const formatTime = unit === "realtime" ? formatMicroseconds : (s) => `${s} ${unit}`;
const profiler = d3.select("#profiler").html("");
const buf = await (await fetch(path)).arrayBuffer();
const buf = cache[path] ?? await fetchValue(path);
const view = new DataView(buf);
let offset = 0;
const u8 = () => { const ret = view.getUint8(offset); offset += 1; return ret; }
@@ -593,6 +593,11 @@ hljs.registerLanguage("cpp", (hljs) => ({
contains: [{ begin: '\\b(?:float|half)[0-9]+\\b', className: 'type' }, ...hljs.getLanguage('cpp').contains]
}));
async function fetchValue(path) {
const res = await fetch(path);
return (await (res.headers.get("content-type") === "application/json" ? res.json() : res.arrayBuffer()));
}
var ret = [];
var cache = {};
var ctxs = null;
@@ -650,7 +655,7 @@ async function main() {
// ** left sidebar context list
if (ctxs == null) {
ctxs = [{ name:"Profiler", steps:[] }];
for (const r of (await (await fetch("/ctxs")).json())) ctxs.push(r);
for (const r of await fetchValue("/ctxs")) ctxs.push(r);
const ctxList = document.querySelector(".ctx-list");
for (const [i,{name, steps}] of ctxs.entries()) {
const ul = ctxList.appendChild(document.createElement("ul"));
@@ -703,8 +708,8 @@ async function main() {
}
// ** Disassembly view
if (ckey.startsWith("/render")) {
if (step.fmt === "timeline") return renderProfiler(ckey, "clk"); // cycles on the x axis
if (!(ckey in cache)) cache[ckey] = ret = await (await fetch(ckey)).json();
if (!(ckey in cache)) cache[ckey] = ret = await fetchValue(ckey);
if (ret instanceof ArrayBuffer) return renderProfiler(ckey, "clk"); // cycles on the x axis
displaySelection("#custom");
metadata.innerHTML = "";
const root = d3.create("div").classed("raw-text", true).node();

View File

@@ -219,8 +219,7 @@ def load_sqtt(profile:list[ProfileEvent]) -> None:
for name,waves in rctx.inst_execs.items():
events:list[ProfileEvent] = []
prg = trace.keys[r].ret if (r:=ref_map.get(name)) else None
steps.append(first:={"name":prg.name if prg is not None else name, "query":f"/render?ctx={len(ctxs)}&step={len(steps)}&fmt=counters",
"depth":0, "fmt":"timeline"})
steps.append(first:={"name":prg.name if prg is not None else name, "query":f"/render?ctx={len(ctxs)}&step={len(steps)}&fmt=counters", "depth":0})
# Idle: The total time gap between the completion of previous instruction and the beginning of the current instruction.
# The idle time can be caused by: