This commit is contained in:
2026-08-15 23:24:23 +08:00
parent 023250c0fc
commit 7a94264c13
32 changed files with 1450 additions and 290 deletions
+54 -11
View File
@@ -48,6 +48,8 @@ inline const char* execution_status(Node_Execution_Status status) noexcept {
return "complete";
case Node_Execution_Status::failed:
return "failed";
case Node_Execution_Status::cancelled:
return "cancelled";
}
return "pending";
}
@@ -188,7 +190,12 @@ inline Json node_analysis_json(const Node_Frame_Analysis& node) {
{"node_id", node.node_id},
{"duration_ns", node.duration_ns},
{"cpu_duration_ns", node.cpu_duration_ns},
{"render_domain_cpu_duration_ns", node.render_domain_cpu_duration_ns},
{"total_cpu_work_duration_ns", node.total_cpu_work_duration_ns},
{"external_duration_ns", node.external_duration_ns},
{"render_domain_queue_wait_ns", node.render_domain_queue_wait_ns},
{"gpu_completion_wait_ns", node.gpu_completion_wait_ns},
{"gpu_execution_duration_ns", node.gpu_execution_duration_ns},
{"start_offset_ns", node.start_offset_ns},
{"end_offset_ns", node.end_offset_ns},
{"dependency_ready_time_ns", node.dependency_ready_time_ns},
@@ -223,11 +230,25 @@ inline Json frame_json(const Captured_Frame& frame) {
{"total_render_duration_ns", frame.analysis.total_render_duration_ns},
{"critical_path_duration_ns", frame.analysis.critical_path_duration_ns},
{"total_work_duration_ns", frame.analysis.total_work_duration_ns},
{"scheduler_work_duration_ns", frame.analysis.scheduler_work_duration_ns},
{"render_domain_work_duration_ns",
frame.analysis.render_domain_work_duration_ns},
{"total_external_duration_ns",
frame.analysis.total_external_duration_ns},
{"parallel_overlap_ns", frame.analysis.parallel_overlap_ns},
{"peak_parallelism", frame.analysis.peak_parallelism},
{"average_parallelism", frame.analysis.average_parallelism},
{"total_render_domain_queue_wait_ns",
frame.analysis.total_render_domain_queue_wait_ns},
{"total_gpu_completion_wait_ns",
frame.analysis.total_gpu_completion_wait_ns},
{"total_gpu_execution_duration_ns",
frame.analysis.total_gpu_execution_duration_ns},
{"scheduler_parallel_overlap_ns",
frame.analysis.scheduler_parallel_overlap_ns},
{"scheduler_peak_parallelism",
frame.analysis.scheduler_peak_parallelism},
{"average_cpu_concurrency", frame.analysis.average_cpu_concurrency},
{"scheduler_average_parallelism",
frame.analysis.scheduler_average_parallelism},
{"render_domain_utilization", frame.analysis.render_domain_utilization},
{"critical_path", frame.analysis.critical_path},
{"bottleneck_nodes", frame.analysis.bottleneck_nodes},
{"nodes", std::move(nodes)},
@@ -248,9 +269,18 @@ inline Json node_statistics_json(const Node_Statistics& statistics) {
{"minimum_ns", statistics.minimum_ns},
{"maximum_ns", statistics.maximum_ns},
{"average_cpu_ns", statistics.average_cpu_ns},
{"average_render_domain_cpu_ns", statistics.average_render_domain_cpu_ns},
{"average_total_cpu_work_ns", statistics.average_total_cpu_work_ns},
{"average_external_ns", statistics.average_external_ns},
{"average_render_domain_queue_wait_ns",
statistics.average_render_domain_queue_wait_ns},
{"average_gpu_completion_wait_ns",
statistics.average_gpu_completion_wait_ns},
{"average_gpu_execution_ns", statistics.average_gpu_execution_ns},
{"p95_cpu_ns", statistics.p95_cpu_ns},
{"p95_render_domain_cpu_ns", statistics.p95_render_domain_cpu_ns},
{"p95_external_ns", statistics.p95_external_ns},
{"p95_gpu_execution_ns", statistics.p95_gpu_execution_ns},
{"critical_path_frequency", statistics.critical_path_frequency},
{"average_scheduler_wait_ns", statistics.average_scheduler_wait_ns}
};
@@ -267,8 +297,11 @@ inline Json plan_statistics_json(const Plan_Version_Statistics& statistics) {
{"render_p50_ns", statistics.render_p50_ns},
{"render_p95_ns", statistics.render_p95_ns},
{"render_maximum_ns", statistics.render_maximum_ns},
{"average_parallelism", statistics.average_parallelism},
{"peak_parallelism", statistics.peak_parallelism},
{"average_cpu_concurrency", statistics.average_cpu_concurrency},
{"scheduler_average_parallelism",
statistics.scheduler_average_parallelism},
{"render_domain_utilization", statistics.render_domain_utilization},
{"scheduler_peak_parallelism", statistics.scheduler_peak_parallelism},
{"scheduler_wait_average_ns", statistics.scheduler_wait_average_ns},
{"scheduler_wait_p95_ns", statistics.scheduler_wait_p95_ns},
{"nodes", std::move(nodes)}
@@ -291,12 +324,17 @@ inline Json session_summary_json(const Capture_Session& session) {
std::vector<std::uint64_t> durations;
std::vector<std::uint64_t> waits;
std::map<Render_Node_Id, std::size_t> critical_frequency;
double parallelism{};
std::size_t peak{};
double cpu_concurrency{};
double scheduler_parallelism{};
double render_domain_utilization{};
std::size_t scheduler_peak{};
for (const auto& frame : session.frames) {
durations.push_back(frame.analysis.total_render_duration_ns);
parallelism += frame.analysis.average_parallelism;
peak = std::max(peak, frame.analysis.peak_parallelism);
cpu_concurrency += frame.analysis.average_cpu_concurrency;
scheduler_parallelism += frame.analysis.scheduler_average_parallelism;
render_domain_utilization += frame.analysis.render_domain_utilization;
scheduler_peak = std::max(
scheduler_peak, frame.analysis.scheduler_peak_parallelism);
for (const auto& node : frame.analysis.nodes)
waits.push_back(node.scheduler_wait_ns);
for (Render_Node_Id node_id : frame.analysis.critical_path)
@@ -313,8 +351,13 @@ inline Json session_summary_json(const Capture_Session& session) {
{"render_p50_ns", percentile(durations, 0.50)},
{"render_p95_ns", percentile(durations, 0.95)},
{"render_maximum_ns", durations.empty() ? 0 : *std::max_element(durations.begin(), durations.end())},
{"average_parallelism", session.frames.empty() ? 0.0 : parallelism / session.frames.size()},
{"peak_parallelism", peak},
{"average_cpu_concurrency",
session.frames.empty() ? 0.0 : cpu_concurrency / session.frames.size()},
{"scheduler_average_parallelism",
session.frames.empty() ? 0.0 : scheduler_parallelism / session.frames.size()},
{"render_domain_utilization",
session.frames.empty() ? 0.0 : render_domain_utilization / session.frames.size()},
{"scheduler_peak_parallelism", scheduler_peak},
{"scheduler_wait_average_ns", waits.empty() ? 0.0 : wait_sum / waits.size()},
{"scheduler_wait_p95_ns", percentile(waits, 0.95)},
{"critical_path_frequency", std::move(critical)}
+3 -1
View File
@@ -480,7 +480,9 @@ public:
{"queued", runtime.render_domain.queued},
{"peak_queued", runtime.render_domain.peak_queued},
{"backpressure_count", runtime.render_domain.backpressure_count},
{"backpressure_wait_ns", runtime.render_domain.backpressure_wait_ns}}},
{"backpressure_wait_ns", runtime.render_domain.backpressure_wait_ns},
{"unhandled_exception_count",
runtime.render_domain_unhandled_exception_count}}},
{"gpu_completion",
{{"capacity", runtime.gpu_completion.capacity},
{"active", runtime.gpu_completion.active},
+10 -2
View File
@@ -535,7 +535,7 @@ TEST(RenderiveWebGallery, PerformanceCaptureReturnsPlanFrameAnalysisAndStatistic
EXPECT_FALSE(captured.at("active"));
ASSERT_EQ(captured.at("frames").size(), 2U);
EXPECT_TRUE(captured.at("summary").contains("render_p95_ns"));
EXPECT_TRUE(captured.at("summary").contains("average_parallelism"));
EXPECT_TRUE(captured.at("summary").contains("average_cpu_concurrency"));
EXPECT_TRUE(captured.at("summary").contains("scheduler_wait_p95_ns"));
EXPECT_FALSE(captured.at("node_statistics").empty());
EXPECT_FALSE(captured.at("plan_statistics").empty());
@@ -555,7 +555,12 @@ TEST(RenderiveWebGallery, PerformanceCaptureReturnsPlanFrameAnalysisAndStatistic
EXPECT_TRUE(execution.contains("attachments"));
const auto& analysis = frame.at("analysis");
EXPECT_TRUE(analysis.contains("critical_path"));
EXPECT_TRUE(analysis.contains("parallel_overlap_ns"));
EXPECT_TRUE(analysis.contains("scheduler_parallel_overlap_ns"));
EXPECT_TRUE(analysis.contains("scheduler_work_duration_ns"));
EXPECT_TRUE(analysis.contains("render_domain_work_duration_ns"));
EXPECT_TRUE(analysis.contains("total_gpu_execution_duration_ns"));
EXPECT_TRUE(analysis.contains("average_cpu_concurrency"));
EXPECT_TRUE(analysis.contains("render_domain_utilization"));
EXPECT_TRUE(analysis.contains("workers"));
const auto version = frame.at("render_plan_version");
EXPECT_TRUE(std::any_of(capture.at("plans").begin(), capture.at("plans").end(),
@@ -573,7 +578,10 @@ TEST(RenderiveWebGallery, PerformanceCaptureReturnsPlanFrameAnalysisAndStatistic
EXPECT_TRUE(statistic.contains("p95_ns"));
EXPECT_TRUE(statistic.contains("p99_ns"));
EXPECT_TRUE(statistic.contains("average_cpu_ns"));
EXPECT_TRUE(statistic.contains("average_render_domain_cpu_ns"));
EXPECT_TRUE(statistic.contains("average_total_cpu_work_ns"));
EXPECT_TRUE(statistic.contains("average_external_ns"));
EXPECT_TRUE(statistic.contains("average_gpu_execution_ns"));
EXPECT_TRUE(statistic.contains("p95_cpu_ns"));
EXPECT_TRUE(statistic.contains("p95_external_ns"));
EXPECT_TRUE(statistic.contains("critical_path_frequency"));