优化了 还是卡

This commit is contained in:
2026-08-25 15:34:31 +08:00
parent fa93927d81
commit 5437b1b267
5 changed files with 58 additions and 13 deletions
+19 -9
View File
@@ -87,7 +87,8 @@ type Taskflow_Frame_Response = {protocol: "aethera.taskflow.frames"; version: 1;
captured: number; complete: boolean; frames: Taskflow_Frame_Trace[]};
type Taskflow_Worker_State = {id: number; task_count: number; current_queue_size: number; current_queue_capacity: number;
peak_queue_size: number; max_queue_capacity: number; active_task: {native_id: string; type: string; time_ns: number};
task_time_ns: number; busy_time_ns: number; idle_time_ns: number; min_task_time_ns: number; max_task_time_ns: number; utilization: number};
task_time_ns: number; busy_time_ns: number; cpu_time_ns: number; non_cpu_time_ns: number; idle_time_ns: number;
min_task_time_ns: number; max_task_time_ns: number; utilization: number; cpu_utilization: number};
type Taskflow_Type_State = {name: string; count: number; total_time_ns: number; min_time_ns: number; max_time_ns: number};
type Taskflow_Runtime_State = {protocol: "aethera.taskflow.runtime"; version: 1; worker_count: number; active_topologies: number;
active_taskflows: number; peak_active_taskflows: number; completed_taskflows: number; failed_taskflows: number;
@@ -95,7 +96,8 @@ type Taskflow_Runtime_State = {protocol: "aethera.taskflow.runtime"; version: 1;
named_tasks: number; peak_worker_queue_size: number; max_worker_queue_capacity: number; max_predecessors: number;
max_successors: number; max_strong_dependencies: number; max_weak_dependencies: number;
longest_task: {native_id: string; name: string; type: string; time_ns: number}; total_task_time_ns: number;
worker_busy_time_ns: number; observed_wall_time_ns: number; worker_utilization: number;
worker_busy_time_ns: number; worker_cpu_time_ns: number; observed_wall_time_ns: number;
worker_utilization: number; worker_cpu_utilization: number;
task_types: Taskflow_Type_State[]; workers: Taskflow_Worker_State[]};
const default_plot_execution_policy = (): Plot_Execution_Policy => ({visible: true});
@@ -1221,6 +1223,11 @@ function taskflow_graph_analysis(graph: Taskflow_Graph_Trace, executions: Taskfl
const last_completed = rows.length ? Math.max(...rows.map(row => row.completed_ms)) : graph.finished_ms;
const longest = rows.reduce<Taskflow_Execution_Trace | null>(
(result, row) => !result || row.duration_ms > result.duration_ms ? row : result, null);
const longest_non_cpu = rows.reduce<Taskflow_Execution_Trace | null>((result, row) => {
const value = Math.max(0, row.duration_ms - row.cpu_duration_ms);
const previous = result ? Math.max(0, result.duration_ms - result.cpu_duration_ms) : -1;
return value > previous ? row : result;
}, null);
const events = rows.flatMap(row => [
{time: row.started_ms, delta: 1},
{time: row.finished_ms, delta: -1}
@@ -1281,7 +1288,7 @@ function taskflow_graph_analysis(graph: Taskflow_Graph_Trace, executions: Taskfl
maximum_parallelism,
layer_count: width_by_level.size,
parallel_layer_count: [...width_by_level.values()].filter(width => width > 1).length,
longest
longest, longest_non_cpu
};
}
@@ -1459,7 +1466,7 @@ function Taskflow_Frame_Pane({plot}: {plot: Plot}) {
<div title="提交 Taskflow 到整个 Topology 完成的墙钟时间,包含 Executor 排队。"><dt>Topology </dt><dd>{milliseconds(graph_analysis.wall_time)}</dd></div>
<div title="所有节点任务体墙钟时长之和;包含 worker 被 OS 抢占或任务体内阻塞的时间。"><dt></dt><dd>{milliseconds(graph_analysis.execution_time)}</dd></div>
<div title="通过 worker 线程 CPU 时钟测得,不包含 OS 抢占和任务内睡眠。"><dt> CPU</dt><dd>{milliseconds(graph_analysis.cpu_execution_time)}</dd></div>
<div title="任务体墙钟减去线程 CPU 时间;包含 OS 抢占、内核等待或任务体内阻塞。"><dt>Worker /</dt><dd>{milliseconds(graph_analysis.descheduled_time)}</dd></div>
<div title="任务体墙钟减去 Windows 线程 CPU 计费时间。短任务受约 15.625 ms 计费粒度影响,只能视为估算,不能单独证明锁等待或 OS 抢占。"><dt> CPU </dt><dd>{milliseconds(graph_analysis.descheduled_time)}</dd></div>
<div title="Topology 墙钟中至少有一个节点任务体正在执行的区间并集。"><dt></dt><dd>{milliseconds(graph_analysis.body_wall_time)}</dd></div>
<div title="Topology 墙钟中只有 Observer on_entry/on_exit 在执行、没有任务体执行的区间。"><dt>Observer </dt><dd>{milliseconds(graph_analysis.observer_wall_time)}</dd></div>
<div title="所有节点 Observer entry 墙钟耗时之和,包含并行重叠。"><dt>Observer entry </dt><dd>{milliseconds(graph_analysis.observer_entry_time)}</dd></div>
@@ -1474,6 +1481,7 @@ function Taskflow_Frame_Pane({plot}: {plot: Plot}) {
<div title="Observer 时间区间内同时执行的最大节点数量。"><dt></dt><dd>{graph_analysis.maximum_parallelism}</dd></div>
<div title="同一层节点没有相互依赖,可以并行;串行图的并行层数量为零。"><dt> / </dt><dd>{graph_analysis.layer_count} / {graph_analysis.parallel_layer_count}</dd></div>
<div title={graph_analysis.longest?.node_id}><dt></dt><dd>{graph_analysis.longest ? milliseconds(graph_analysis.longest.duration_ms) : "--"}</dd></div>
<div title={graph_analysis.longest_non_cpu?.node_id}><dt> CPU </dt><dd>{graph_analysis.longest_non_cpu ? `${taskflow_node_name(graph_analysis.longest_non_cpu.node_id.split("/").at(-1) ?? graph_analysis.longest_non_cpu.node_id)} · ${milliseconds(Math.max(0, graph_analysis.longest_non_cpu.duration_ms - graph_analysis.longest_non_cpu.cpu_duration_ms))}` : "--"}</dd></div>
{graph.stage === "render_2d.paint" && paint_analysis ? <>
<div title="同一物理帧 paint_started 到 paint_finished 的完整区间。"><dt> Paint </dt><dd>{milliseconds(paint_analysis.total)}</dd></div>
<div title="主帧 ensure_size 与完整像素清屏。"><dt></dt><dd>{milliseconds(paint_analysis.frame_target)}</dd></div>
@@ -1505,18 +1513,20 @@ function Taskflow_Runtime_Pane() {
return <section className="workspacePane"><header className="taskflowRuntimeHeader"><div><span className="eyebrow"></span><h2>Taskflow </h2><p> Observer Taskflow </p></div><button onClick={() => void load()}></button></header>
<div className="workspaceBody taskflowRuntimePane">{error ? <p className="taskflowError">{error}</p> : null}{state ? <>
<dl className="taskflowRuntimeSummary">
<div><dt>Worker</dt><dd>{state.worker_count}</dd></div><div><dt></dt><dd>{state.worker_utilization.toFixed(1)}%</dd></div>
<div><dt>Worker</dt><dd>{state.worker_count}</dd></div><div title="Worker 位于最外层任务体内的累计墙钟占比,不等同于 CPU 利用率。"><dt></dt><dd>{state.worker_utilization.toFixed(1)}%</dd></div>
<div title="按 Worker 最外层活跃区间累计的线程 CPU 时间占比。"><dt>线 CPU </dt><dd>{state.worker_cpu_utilization.toFixed(1)}%</dd></div>
<div><dt> Worker</dt><dd>{state.active_workers}/{state.worker_count}</dd></div><div><dt></dt><dd>{state.active_tasks}</dd></div>
<div><dt> Topology</dt><dd>{state.active_topologies}</dd></div><div><dt> Taskflow</dt><dd>{state.active_taskflows}</dd></div>
<div><dt></dt><dd>{state.observed_tasks.toLocaleString("zh-CN")}</dd></div><div><dt> Taskflow</dt><dd>{state.failed_taskflows}</dd></div>
<div><dt></dt><dd>{state.peak_worker_queue_size}</dd></div><div title={`${state.longest_task.name || state.longest_task.native_id} · ${state.longest_task.type}`}><dt></dt><dd>{nanoseconds(state.longest_task.time_ns)}</dd></div>
</dl>
<p className="diagnosticNotice">Observer Executor Taskflow Observer DAG Worker </p>
<p className="diagnosticNotice"> Worker CPU 使线 CPU OS Executor </p>
<section className="taskflowRuntimeSection"><header><strong>Worker </strong><span> GET </span></header><div className="taskflowWorkerGrid">{state.workers.map(worker => <article key={worker.id}>
<header><strong>Worker {worker.id}</strong><span>{worker.utilization.toFixed(1)}%</span></header>
<div className="taskflowUtilization"><i style={{width: `${Math.min(100, worker.utilization)}%`}}/></div>
<header><strong>Worker {worker.id}</strong><span> {worker.utilization.toFixed(1)}% · CPU {worker.cpu_utilization.toFixed(1)}%</span></header>
<div className="taskflowUtilization" title={`任务体墙钟 ${worker.utilization.toFixed(1)}% / 线程 CPU ${worker.cpu_utilization.toFixed(1)}%`}><i style={{width: `${Math.min(100, worker.utilization)}%`}}/><b style={{width: `${Math.min(100, worker.cpu_utilization)}%`}}/></div>
<dl><div><dt></dt><dd>{worker.task_count}</dd></div><div><dt> /</dt><dd>{worker.current_queue_size}/{worker.peak_queue_size}</dd></div>
<div><dt></dt><dd>{nanoseconds(worker.max_task_time_ns)}</dd></div><div><dt></dt><dd>{worker.active_task.time_ns ? nanoseconds(worker.active_task.time_ns) : "空闲"}</dd></div></dl>
<div><dt></dt><dd>{nanoseconds(worker.max_task_time_ns)}</dd></div><div><dt></dt><dd>{worker.active_task.time_ns ? nanoseconds(worker.active_task.time_ns) : "空闲"}</dd></div>
<div><dt> CPU</dt><dd>{nanoseconds(worker.cpu_time_ns)}</dd></div><div><dt> CPU </dt><dd>{nanoseconds(worker.non_cpu_time_ns)}</dd></div></dl>
{worker.active_task.time_ns ? <code className="taskflowActiveTask" title={worker.active_task.native_id}>{worker.active_task.type} · {worker.active_task.native_id}</code> : null}
</article>)}</div></section>
<section className="taskflowRuntimeSection"><header><strong>Taskflow </strong><span> Observer TaskType </span></header>
+5 -3
View File
@@ -232,12 +232,14 @@ canvas { display: block; width: 100%; height: 100%; background: #070d18; }
.taskflowRuntimeHeader { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 17px 16px 14px; border-bottom: 1px solid #20314b; background: #0b1524; }
.taskflowRuntimeHeader h2 { margin: 4px 0 0; font-size: 21px; }
.taskflowRuntimeHeader p { margin: 5px 0 0; color: #71839e; font-size: 11px; }
.taskflowWorkerGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 9px; padding: 11px; }
.taskflowWorkerGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); align-content: start; gap: 9px; max-height: min(58vh, 720px); overflow-y: auto; padding: 11px; scrollbar-gutter: stable; }
.taskflowWorkerGrid article { padding: 10px; border: 1px solid #1f334e; border-radius: 8px; background: #091321; }
.taskflowWorkerGrid article > header { display: flex; justify-content: space-between; color: #dce8f8; font-size: 11px; }
.taskflowWorkerGrid article > header span { color: #5ce4c2; font: 11px/1 ui-monospace, monospace; }
.taskflowUtilization { height: 6px; overflow: hidden; margin: 9px 0; border-radius: 99px; background: #18273b; }
.taskflowUtilization i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #3aa58d, #5ce4c2); }
.taskflowUtilization { position: relative; height: 9px; overflow: hidden; margin: 9px 0; border-radius: 99px; background: #18273b; }
.taskflowUtilization i, .taskflowUtilization b { position: absolute; left: 0; display: block; border-radius: inherit; }
.taskflowUtilization i { top: 0; height: 100%; background: #2b887c; }
.taskflowUtilization b { bottom: 0; height: 4px; background: #5ce4c2; }
.taskflowWorkerGrid dl { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin: 0; }
.taskflowWorkerGrid dl > div { display: flex; justify-content: space-between; gap: 5px; color: #71839e; font-size: 9px; }
.taskflowWorkerGrid dd { margin: 0; color: #aec0d8; font-family: ui-monospace, monospace; }