架构微调

This commit is contained in:
2026-08-11 09:24:12 +08:00
parent 14a6e97b64
commit 462baeca76
14 changed files with 179 additions and 110 deletions
+17 -27
View File
@@ -226,14 +226,6 @@ public:
return plot_.refresh_feedback_snapshot().next_refresh_interval_ns;
}
[[nodiscard]] std::uint64_t web_pixel_interval_ns() const {
return frequency_interval_ns(number_value(state_, "pixel_stream_fps"));
}
[[nodiscard]] std::uint64_t automatic_render_interval_ns() const {
return std::max(kernel_refresh_interval_ns(), web_pixel_interval_ns());
}
void set_client_metrics(double transport_fps, double presentation_fps,
std::uint64_t buffered_bytes,
std::uint64_t changed_pixel_frames,
@@ -630,6 +622,7 @@ public:
{"render_duration_ns", observer.render_duration_ns},
{"target_interval_ns", observer.target_interval_ns},
{"bottleneck_duration_ns", observer.bottleneck_duration_ns},
{"consumer_interval_ns", observer.consumer_interval_ns},
{"next_refresh_interval_ns", observer.next_refresh_interval_ns},
{"paint_lease_wait_ns", observer.paint_lease_wait_ns},
{"paint_state_wait_ns", observer.paint_state_wait_ns},
@@ -657,28 +650,24 @@ public:
if (frame_mode_ == Gallery_Frame_Mode::Low_Latency) {
telemetry["render_fps"] = plot_.max_render_fps();
telemetry["refresh_feedback_hz"] = plot_.refresh_feedback_snapshot().frequency_hz;
const auto kernel_interval_ns = kernel_refresh_interval_ns();
const auto web_interval_ns = web_pixel_interval_ns();
const auto scheduler_interval_ns = std::max(kernel_interval_ns, web_interval_ns);
const auto scheduler_limit_source = web_interval_ns > kernel_interval_ns ?
"web_pixel_stream" : observer.limit_state;
const auto scheduler_interval_ns = kernel_refresh_interval_ns();
telemetry["low_latency_limit"] = {
{"current", scheduler_limit_source},
{"kernel_current", observer.limit_state},
{"current", observer.limit_state},
{"frequency_limited", observer.limit_state == "frequency_limited"},
{"paint_limited", observer.limit_state == "paint_limited"},
{"render_limited", observer.limit_state == "render_limited"},
{"web_pixel_stream_limited", web_interval_ns > kernel_interval_ns},
{"consumer_limited", observer.limit_state == "consumer_limited"},
{"configured_frequency_hz", observer.frequency_hz},
{"consumer_feedback_source", "web_pixel_stream"},
{"web_pixel_stream_fps", number_value(state_, "pixel_stream_fps")},
{"target_interval_ns", observer.target_interval_ns},
{"paint_duration_ns", observer.paint_duration_ns},
{"render_duration_ns", observer.render_duration_ns},
{"bottleneck_duration_ns", observer.bottleneck_duration_ns},
{"kernel_refresh_interval_ns", kernel_interval_ns},
{"web_pixel_stream_interval_ns", web_interval_ns},
{"consumer_interval_ns", observer.consumer_interval_ns},
{"scheduler_interval_ns", scheduler_interval_ns},
{"scheduler_frequency_hz", 1'000'000'000.0 / static_cast<double>(scheduler_interval_ns)}
{"scheduler_frequency_hz", scheduler_interval_ns == 0 ? 0.0 :
1'000'000'000.0 / static_cast<double>(scheduler_interval_ns)}
};
}
if (primary_) {
@@ -917,10 +906,7 @@ private:
const double pixel_megabytes_per_second = recent_pixel_megabytes_per_second(
pixel_history_, now);
const bool low_latency = frame_mode_ == Gallery_Frame_Mode::Low_Latency;
const auto kernel_interval_ns = low_latency ? kernel_refresh_interval_ns() : 0;
const auto web_interval_ns = low_latency ? web_pixel_interval_ns() : 0;
const auto scheduler_interval_ns = low_latency ?
std::max(kernel_interval_ns, web_interval_ns) : 0;
const auto scheduler_interval_ns = low_latency ? kernel_refresh_interval_ns() : 0;
const nlohmann::json line{
{"event", "gallery_performance"},
{"unix_ms", unix_ms},
@@ -932,8 +918,8 @@ private:
{"automatic_scheduler_interval_ns", scheduler_interval_ns},
{"automatic_scheduler_fps", scheduler_interval_ns == 0 ? 0.0 :
1'000'000'000.0 / static_cast<double>(scheduler_interval_ns)},
{"automatic_scheduler_limit_source", !low_latency ? "not_applicable" :
(web_interval_ns > kernel_interval_ns ? "web_pixel_stream" : observer.limit_state)},
{"automatic_scheduler_limit_source", low_latency ? observer.limit_state : "not_applicable"},
{"consumer_feedback_interval_ns", low_latency ? observer.consumer_interval_ns : 0},
{"backend_render_fps", recent_rate(render_history_, now)},
{"pixel_response_fps", pixel_fps},
{"client_transport_fps", client_transport_fps_},
@@ -965,6 +951,7 @@ private:
{"paint_duration_ns", observer.paint_duration_ns},
{"render_duration_ns", observer.render_duration_ns},
{"bottleneck_duration_ns", observer.bottleneck_duration_ns},
{"consumer_interval_ns", observer.consumer_interval_ns},
{"next_refresh_interval_ns", observer.next_refresh_interval_ns},
{"paint_lease_wait_ns", observer.paint_lease_wait_ns},
{"paint_state_wait_ns", observer.paint_state_wait_ns},
@@ -1218,8 +1205,11 @@ private:
void apply_state() {
plot_.set_background_color(color_from_hex(string_value(state_, "background_color")));
if (frame_mode_ == Gallery_Frame_Mode::Low_Latency)
if (frame_mode_ == Gallery_Frame_Mode::Low_Latency) {
plot_.set_max_render_fps(number_value(state_, "max_render_fps"));
plot_.set_consumer_feedback(
{frequency_interval_ns(number_value(state_, "pixel_stream_fps"))});
}
set_performance_plot_name(plot_, case_id_ + "/" + std::string(frame_mode_name(frame_mode_)));
set_performance_overlay_enabled(plot_, bool_value(state_, "performance_overlay"));
if (primary_) {
@@ -1560,7 +1550,7 @@ struct Gallery_Plot_Session::Impl {
}
(void)scene->render_latest_frame();
const auto interval = std::chrono::nanoseconds(
std::max<std::uint64_t>(1, scene->automatic_render_interval_ns()));
std::max<std::uint64_t>(1, scene->kernel_refresh_interval_ns()));
if (next_deadline + interval < cycle_started)
next_deadline = cycle_started;
next_deadline += interval;
+2 -2
View File
@@ -127,9 +127,9 @@ void append_common(std::vector<Control_Definition>& result, Gallery_Frame_Mode f
30, 0.01, 1'000'000'000, 1, "Low_Latency_Strategy", false,
"Kernel 接受任意有限正频率;高目标用于触发并观察 Painter 或后台 Render 瓶颈。"));
result.push_back(number("pixel_stream_fps", "WebSocket 像素 FPS",
"WebSocket_Pixel_Stream::set_pull_frequency", 30, 1, 60, 1,
"Plot_Core::set_consumer_feedback", 30, 1, 60, 1,
"Web Transport", false,
"限制浏览器拉取完整 RGBA 像素图的频率,并作为 Web 自动低延迟调度的消费频率上限"));
"限制浏览器拉取完整 RGBA 像素图的频率;Web 适配层将该频率转换为通用消费者反馈,Kernel 不感知 WebSocket"));
}
result.push_back(flag("performance_overlay", "性能叠层", "set_performance_overlay_enabled",
false, "Plot_Core"));
+23 -14
View File
@@ -841,19 +841,21 @@ TEST(RenderiveWebGallery, ThreeFrameStrategiesExposeTheirRealActionsAndObservers
EXPECT_TRUE(low_telemetry.contains("render_fps"));
ASSERT_TRUE(low_telemetry.contains("low_latency_limit"));
const auto& limit = low_telemetry.at("low_latency_limit");
EXPECT_TRUE(limit.at("paint_limited").get<bool>() ||
limit.at("render_limited").get<bool>());
EXPECT_TRUE(limit.at("consumer_limited").get<bool>());
EXPECT_FALSE(limit.at("frequency_limited").get<bool>());
EXPECT_FALSE(limit.at("paint_limited").get<bool>());
EXPECT_FALSE(limit.at("render_limited").get<bool>());
EXPECT_EQ(limit.at("target_interval_ns"), 1);
EXPECT_EQ(limit.at("consumer_interval_ns"), 33'333'333);
EXPECT_GT(limit.at("bottleneck_duration_ns").get<std::uint64_t>(), 1U);
EXPECT_TRUE(low_telemetry.at("kernel_observer").contains("paint_lease_wait_ns"));
EXPECT_TRUE(low_telemetry.at("kernel_observer").contains("render_finish_state_wait_ns"));
constexpr std::array<std::string_view, 26> observer_fields{
constexpr std::array<std::string_view, 27> observer_fields{
"mode", "last_event", "limit_state", "configured_frequency_hz", "observation_count",
"produced_frame_count", "consumed_frame_count", "dropped_frame_count",
"failed_operation_count", "pending_frame_count", "latest_sequence",
"paint_duration_ns", "render_duration_ns", "target_interval_ns",
"bottleneck_duration_ns", "next_refresh_interval_ns", "paint_lease_wait_ns",
"bottleneck_duration_ns", "consumer_interval_ns", "next_refresh_interval_ns", "paint_lease_wait_ns",
"paint_state_wait_ns", "publish_state_wait_ns", "ready_wait_ns",
"frame_age_at_render_ns", "render_lease_wait_ns", "render_state_wait_ns",
"render_finish_state_wait_ns", "queue_wait_ns", "end_to_end_ns"
@@ -968,10 +970,11 @@ TEST(RenderiveWebGallery, LowLatencyStrategyKeepsForegroundResponsiveUnderAggres
EXPECT_GT(telemetry.at("performance").at("successful_render_count").get<std::uint64_t>(), 4U);
EXPECT_TRUE(observer.at("limit_state") == "frequency_limited" ||
observer.at("limit_state") == "paint_limited" ||
observer.at("limit_state") == "render_limited");
observer.at("limit_state") == "render_limited" ||
observer.at("limit_state") == "consumer_limited");
}
TEST(RenderiveWebGallery, WebPixelStreamCapsAutomaticLowLatencyScheduler) {
TEST(RenderiveWebGallery, WebAdapterPublishesGenericConsumerFeedbackToKernelScheduler) {
Gallery_Plot_Session session(true);
ASSERT_EQ(response_json(session.handle(gallery_request(
Gallery_Request_Kind::Open, open_message("spectrum", "low_latency")))).at("type"),
@@ -980,13 +983,18 @@ TEST(RenderiveWebGallery, WebPixelStreamCapsAutomaticLowLatencyScheduler) {
Gallery_Request_Kind::Patch,
R"({"category":"event","type":"gallery_patch","patch":{"max_render_fps":1000000000,"pixel_stream_fps":20}})")));
ASSERT_EQ(patched.at("type"), "case_state");
const auto& limit = patched.at("telemetry").at("low_latency_limit");
EXPECT_EQ(patched.at("telemetry").at("kernel_observer").at("configured_frequency_hz"),
1'000'000'000.0);
EXPECT_EQ(patched.at("telemetry").at("kernel_observer").at("target_interval_ns"), 1);
EXPECT_EQ(limit.at("current"), "web_pixel_stream");
EXPECT_TRUE(limit.at("web_pixel_stream_limited").get<bool>());
EXPECT_EQ(limit.at("web_pixel_stream_interval_ns"), 50'000'000);
const auto& telemetry = patched.at("telemetry");
const auto& observer = telemetry.at("kernel_observer");
const auto& limit = telemetry.at("low_latency_limit");
EXPECT_EQ(observer.at("configured_frequency_hz"), 1'000'000'000.0);
EXPECT_EQ(observer.at("target_interval_ns"), 1);
EXPECT_EQ(observer.at("consumer_interval_ns"), 50'000'000);
EXPECT_EQ(observer.at("next_refresh_interval_ns"), 50'000'000);
EXPECT_EQ(observer.at("limit_state"), "consumer_limited");
EXPECT_EQ(limit.at("current"), "consumer_limited");
EXPECT_TRUE(limit.at("consumer_limited").get<bool>());
EXPECT_EQ(limit.at("consumer_feedback_source"), "web_pixel_stream");
EXPECT_EQ(limit.at("consumer_interval_ns"), 50'000'000);
EXPECT_EQ(limit.at("scheduler_interval_ns"), 50'000'000);
EXPECT_DOUBLE_EQ(limit.at("scheduler_frequency_hz"), 20.0);
const auto baseline = successful_render_count(session);
@@ -1093,7 +1101,8 @@ TEST(RenderiveWebGallery, ProductionLowLatencySessionRendersWithoutPixelPulls) {
EXPECT_EQ(telemetry.at("kernel_observer").at("target_interval_ns"), 8'333'333);
EXPECT_TRUE(telemetry.at("kernel_observer").at("limit_state") == "frequency_limited" ||
telemetry.at("kernel_observer").at("limit_state") == "paint_limited" ||
telemetry.at("kernel_observer").at("limit_state") == "render_limited");
telemetry.at("kernel_observer").at("limit_state") == "render_limited" ||
telemetry.at("kernel_observer").at("limit_state") == "consumer_limited");
EXPECT_DOUBLE_EQ(telemetry.at("client_performance").at("transport_fps"), 120.0);
EXPECT_DOUBLE_EQ(telemetry.at("client_performance").at("presentation_fps"), 60.0);
EXPECT_EQ(telemetry.at("client_performance").at("changed_pixel_frames"), 17);