架构微调
This commit is contained in:
@@ -78,6 +78,7 @@ public:
|
||||
std::uint64_t consumer_sample_interval_ns{};
|
||||
std::uint64_t consumer_smoothed_interval_ns{};
|
||||
std::uint64_t consumer_variation_ns{};
|
||||
std::uint64_t consumer_safety_interval_ns{};
|
||||
std::uint64_t consumer_interval_ns{};
|
||||
std::uint64_t end_to_end_ns{};
|
||||
std::uint64_t next_refresh_interval_ns{};
|
||||
|
||||
@@ -248,6 +248,7 @@ void Low_Latency_Strategy<Scene_Frame, Mutex, Observer>::clear_consumer_feedback
|
||||
state_.consumer_sample_interval_ns = 0;
|
||||
state_.consumer_smoothed_interval_ns = 0;
|
||||
state_.consumer_variation_ns = 0;
|
||||
state_.consumer_safety_interval_ns = 0;
|
||||
state_.consumer_interval_ns = 0;
|
||||
update_refresh_control();
|
||||
}
|
||||
@@ -368,29 +369,31 @@ void Low_Latency_Strategy<Scene_Frame, Mutex, Observer>::update_refresh_control(
|
||||
}
|
||||
template <class Scene_Frame, Mutex_Type Mutex, class Observer>
|
||||
void Low_Latency_Strategy<Scene_Frame, Mutex, Observer>::update_consumer_estimator(std::uint64_t sample_interval_ns) {
|
||||
const std::uint64_t previous_sample = state_.consumer_sample_interval_ns;
|
||||
state_.consumer_sample_interval_ns = sample_interval_ns;
|
||||
if (!state_.consumer_feedback_enabled) {
|
||||
state_.consumer_feedback_enabled = true;
|
||||
state_.consumer_smoothed_interval_ns = sample_interval_ns;
|
||||
state_.consumer_variation_ns = 0;
|
||||
} else {
|
||||
const std::uint64_t smoothed = state_.consumer_smoothed_interval_ns;
|
||||
const std::uint64_t deviation = sample_interval_ns >= smoothed ?
|
||||
sample_interval_ns - smoothed : smoothed - sample_interval_ns;
|
||||
if (deviation >= state_.consumer_variation_ns)
|
||||
state_.consumer_variation_ns += (deviation - state_.consumer_variation_ns) / 4;
|
||||
const std::uint64_t sample_delta = sample_interval_ns >= previous_sample ?
|
||||
sample_interval_ns - previous_sample : previous_sample - sample_interval_ns;
|
||||
if (sample_delta >= state_.consumer_variation_ns)
|
||||
state_.consumer_variation_ns += (sample_delta - state_.consumer_variation_ns) / 16;
|
||||
else
|
||||
state_.consumer_variation_ns -= (state_.consumer_variation_ns - deviation) / 4;
|
||||
state_.consumer_variation_ns -= (state_.consumer_variation_ns - sample_delta) / 16;
|
||||
if (sample_interval_ns >= state_.consumer_smoothed_interval_ns)
|
||||
state_.consumer_smoothed_interval_ns += (sample_interval_ns - state_.consumer_smoothed_interval_ns) / 8;
|
||||
state_.consumer_smoothed_interval_ns += (sample_interval_ns - state_.consumer_smoothed_interval_ns) / 2;
|
||||
else
|
||||
state_.consumer_smoothed_interval_ns -= (state_.consumer_smoothed_interval_ns - sample_interval_ns) / 8;
|
||||
}
|
||||
const auto maximum = std::numeric_limits<std::uint64_t>::max();
|
||||
const std::uint64_t variation_margin = state_.consumer_variation_ns > maximum / 4 ?
|
||||
maximum : state_.consumer_variation_ns * 4;
|
||||
state_.consumer_interval_ns = state_.consumer_smoothed_interval_ns > maximum - variation_margin ?
|
||||
maximum : state_.consumer_smoothed_interval_ns + variation_margin;
|
||||
const std::uint64_t safety_interval = state_.consumer_smoothed_interval_ns > maximum - variation_margin ?
|
||||
maximum : state_.consumer_smoothed_interval_ns + variation_margin;
|
||||
state_.consumer_interval_ns = std::max(state_.consumer_smoothed_interval_ns, sample_interval_ns);
|
||||
state_.consumer_safety_interval_ns = std::max(state_.consumer_interval_ns, safety_interval);
|
||||
}
|
||||
template <class Scene_Frame, Mutex_Type Mutex, class Observer>
|
||||
void Low_Latency_Strategy<Scene_Frame, Mutex, Observer>::update_state(const Frame& frame) {
|
||||
|
||||
+24
-4
@@ -125,7 +125,7 @@ TEST(low_latency_strategy_test, clamps_extremely_small_frequency_interval_withou
|
||||
}
|
||||
EXPECT_EQ(strategy.state().target_interval_ns, std::numeric_limits<std::uint64_t>::max());
|
||||
}
|
||||
TEST(low_latency_strategy_test, smooths_consumer_feedback_in_kernel) {
|
||||
TEST(low_latency_strategy_test, separates_consumer_rate_from_jitter_safety_margin) {
|
||||
Low_Latency_Test_Time_Source time_source;
|
||||
Low_Latency_Test_Observer observer;
|
||||
auto strategy = make_low_latency_test_strategy(time_source, observer);
|
||||
@@ -136,15 +136,34 @@ TEST(low_latency_strategy_test, smooths_consumer_feedback_in_kernel) {
|
||||
EXPECT_EQ(state.consumer_sample_interval_ns, 10'000'000u);
|
||||
EXPECT_EQ(state.consumer_smoothed_interval_ns, 10'000'000u);
|
||||
EXPECT_EQ(state.consumer_variation_ns, 0u);
|
||||
EXPECT_EQ(state.consumer_safety_interval_ns, 10'000'000u);
|
||||
EXPECT_EQ(state.consumer_interval_ns, 10'000'000u);
|
||||
strategy.set_consumer_feedback({14'000'000});
|
||||
state = strategy.state();
|
||||
EXPECT_EQ(state.consumer_sample_interval_ns, 14'000'000u);
|
||||
EXPECT_EQ(state.consumer_smoothed_interval_ns, 10'500'000u);
|
||||
EXPECT_EQ(state.consumer_variation_ns, 1'000'000u);
|
||||
EXPECT_EQ(state.consumer_interval_ns, 14'500'000u);
|
||||
EXPECT_EQ(state.consumer_smoothed_interval_ns, 12'000'000u);
|
||||
EXPECT_EQ(state.consumer_variation_ns, 250'000u);
|
||||
EXPECT_EQ(state.consumer_safety_interval_ns, 14'000'000u);
|
||||
EXPECT_EQ(state.consumer_interval_ns, 14'000'000u);
|
||||
EXPECT_EQ(state.next_refresh_interval_ns, 14'000'000u);
|
||||
EXPECT_EQ(state.limit_state, Low_Latency_Test_Strategy::Limit_State::consumer_limited);
|
||||
}
|
||||
TEST(low_latency_strategy_test, consumer_jitter_changes_safety_deadline_without_becoming_rate_limit) {
|
||||
Low_Latency_Test_Time_Source time_source;
|
||||
Low_Latency_Test_Observer observer;
|
||||
auto strategy = make_low_latency_test_strategy(time_source, observer);
|
||||
strategy.set_frequency_hz(1000.0);
|
||||
strategy.set_consumer_feedback({20'000'000});
|
||||
strategy.set_consumer_feedback({22'000'000});
|
||||
strategy.set_consumer_feedback({20'000'000});
|
||||
const auto state = strategy.state();
|
||||
EXPECT_EQ(state.consumer_sample_interval_ns, 20'000'000u);
|
||||
EXPECT_EQ(state.consumer_smoothed_interval_ns, 20'875'000u);
|
||||
EXPECT_EQ(state.consumer_variation_ns, 242'187u);
|
||||
EXPECT_EQ(state.consumer_interval_ns, 20'875'000u);
|
||||
EXPECT_EQ(state.consumer_safety_interval_ns, 21'843'748u);
|
||||
EXPECT_EQ(state.next_refresh_interval_ns, 20'875'000u);
|
||||
}
|
||||
TEST(low_latency_strategy_test, allows_frequency_and_consumer_limits_to_be_cleared) {
|
||||
Low_Latency_Test_Time_Source time_source;
|
||||
Low_Latency_Test_Observer observer;
|
||||
@@ -154,6 +173,7 @@ TEST(low_latency_strategy_test, allows_frequency_and_consumer_limits_to_be_clear
|
||||
strategy.clear_consumer_feedback();
|
||||
auto state = strategy.state();
|
||||
EXPECT_FALSE(state.consumer_feedback_enabled);
|
||||
EXPECT_EQ(state.consumer_safety_interval_ns, 0u);
|
||||
EXPECT_EQ(state.consumer_interval_ns, 0u);
|
||||
EXPECT_EQ(state.limit_state, Low_Latency_Test_Strategy::Limit_State::frequency_limited);
|
||||
strategy.clear_frequency_limit();
|
||||
|
||||
Reference in New Issue
Block a user