Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(853)

Unified Diff: webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc

Issue 2982233002: Added implementations for entering/exiting STARTUP, DRAIN, PROBE_BW, PROBE_RTT modes, also updated M (Closed)
Patch Set: Unittest fix Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc
diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc
index a2463fc872e89df01e3260f738a39cf770eb3b23..11979bf4468d1b2291fe92233dcd6573fdfad3f8 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc
@@ -11,13 +11,17 @@
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h"
+#include <stdlib.h>
+
+#include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h"
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h"
+#include "webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h"
namespace webrtc {
namespace testing {
namespace bwe {
namespace {
-const int kFeedbackIntervalsMs = 100;
+const int kFeedbackIntervalsMs = 3;
// BBR uses this value to double sending rate each round trip. Design document
// suggests using this value.
const float kHighGain = 2.885f;
@@ -28,6 +32,23 @@ const float kDrainGain = 1 / kHighGain;
// experiments, according to the design document.
const float kStartupGrowthTarget = 1.25f;
const int kMaxRoundsWithoutGrowth = 3;
+// Pacing gain values for Probe Bandwidth mode.
+const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
+const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
+// The least amount of rounds PROBE_RTT mode should last.
+const int kProbeRttDurationRounds = 1;
+// The least amount of milliseconds PROBE_RTT mode should last.
+const int kProbeRttDurationMs = 200;
+// Gain value for congestion window for assuming that network has no queues.
+const float kTargetCongestionWindowGain = 1;
+// Gain value for congestion window in PROBE_BW mode. In theory it should be
+// equal to 1, but in practice because of delayed acks and the way networks
+// work, it is nice to have some extra room in congestion window for full link
+// utilization. Value chosen by observations on different tests.
+const float kCruisingCongestionWindowGain = 1.5f;
+// Expiration time for min_rtt sample, which is set to 10 seconds according to
+// BBR design doc.
+const int64_t kMinRttFilterSizeMs = 10000;
} // namespace
BbrBweSender::BbrBweSender(Clock* clock)
@@ -35,10 +56,19 @@ BbrBweSender::BbrBweSender(Clock* clock)
clock_(clock),
mode_(STARTUP),
max_bandwidth_filter_(new MaxBandwidthFilter()),
+ min_rtt_filter_(new MinRttFilter()),
+ congestion_window_(new CongestionWindow()),
+ rand_(new Random(time(NULL))),
round_count_(0),
last_packet_sent_(0),
round_trip_end_(0),
- full_bandwidth_reached_(false) {
+ full_bandwidth_reached_(false),
+ cycle_start_time_ms_(0),
+ cycle_index_(0),
+ prior_in_flight_(0),
+ probe_rtt_start_time_ms_(0),
+ minimum_congestion_window_start_time_ms_(),
+ minimum_congestion_window_start_round_(0) {
// Initially enter Startup mode.
EnterStartup();
}
@@ -81,7 +111,7 @@ void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) {
TryUpdatingCyclePhase(now_ms);
break;
case PROBE_RTT:
- TryExitingProbeRtt(now_ms);
+ TryExitingProbeRtt(now_ms, 0);
break;
}
TryEnteringProbeRtt(now_ms);
@@ -89,6 +119,14 @@ void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) {
// controllers.
}
+size_t BbrBweSender::TargetCongestionWindow(float gain) {
+ size_t target_congestion_window =
+ congestion_window_->GetTargetCongestionWindow(
+ max_bandwidth_filter_->max_bandwidth_estimate_bps(),
+ min_rtt_filter_->min_rtt_ms(), gain);
+ return target_congestion_window;
+}
+
bool BbrBweSender::UpdateBandwidthAndMinRtt() {
return false;
}
@@ -107,14 +145,78 @@ void BbrBweSender::TryExitingStartup() {
}
}
-void BbrBweSender::TryExitingDrain(int64_t now_ms) {}
+void BbrBweSender::TryExitingDrain(int64_t now_ms) {
+ if (congestion_window_->data_inflight() <=
+ TargetCongestionWindow(kTargetCongestionWindowGain))
+ EnterProbeBw(now_ms);
+}
-void BbrBweSender::EnterProbeBw(int64_t now_ms) {}
+// Start probing with a random gain value, which is different form 0.75,
+// starting with 0.75 doesn't offer any benefits as there are no queues to be
+// drained.
+void BbrBweSender::EnterProbeBw(int64_t now_ms) {
+ mode_ = PROBE_BW;
+ congestion_window_gain_ = kCruisingCongestionWindowGain;
+ int index = rand_->Rand(kGainCycleLength - 2);
+ if (index == 1)
+ index = kGainCycleLength - 1;
+ pacing_gain_ = kPacingGain[index];
+ cycle_start_time_ms_ = now_ms;
+ cycle_index_ = index;
+}
-void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {}
+void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {
+ // Each phase should last rougly min_rtt ms time.
+ bool advance_cycle_phase = false;
+ if (min_rtt_filter_->min_rtt_ms())
+ advance_cycle_phase =
+ now_ms - cycle_start_time_ms_ > *min_rtt_filter_->min_rtt_ms();
+ // If BBR was probing and it couldn't increase data inflight sufficiently in
+ // one min_rtt time, continue probing. BBR design doc isn't clear about this,
+ // but condition helps in quicker ramp-up and performs better.
+ if (pacing_gain_ > 1.0 &&
+ prior_in_flight_ < TargetCongestionWindow(pacing_gain_))
+ advance_cycle_phase = false;
+ // If BBR has already drained queues there is no point in continuing draining
+ // phase.
+ if (pacing_gain_ < 1.0 && prior_in_flight_ <= TargetCongestionWindow(1))
+ advance_cycle_phase = true;
+ if (advance_cycle_phase) {
+ cycle_index_++;
+ cycle_index_ %= kGainCycleLength;
+ pacing_gain_ = kPacingGain[cycle_index_];
+ cycle_start_time_ms_ = now_ms;
+ }
+}
-void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {}
-void BbrBweSender::TryExitingProbeRtt(int64_t now_ms) {}
+void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {
+ if (min_rtt_filter_->min_rtt_expired(now_ms, kMinRttFilterSizeMs) &&
+ mode_ != PROBE_RTT) {
+ mode_ = PROBE_RTT;
+ pacing_gain_ = 1;
+ probe_rtt_start_time_ms_ = now_ms;
+ minimum_congestion_window_start_time_ms_.reset();
+ }
+}
+
+// minimum_congestion_window_start_time_'s value is set to the first moment when
+// data inflight was less then kMinimumCongestionWindowBytes, we should make
+// sure that BBR has been in PROBE_RTT mode for at least one round or 200ms.
+void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, int64_t round) {
+ if (!minimum_congestion_window_start_time_ms_) {
+ if (congestion_window_->data_inflight() <=
+ CongestionWindow::kMinimumCongestionWindowBytes) {
+ *minimum_congestion_window_start_time_ms_ = now_ms;
+ minimum_congestion_window_start_round_ = round;
+ }
+ } else {
+ if (now_ms - *minimum_congestion_window_start_time_ms_ >=
+ kProbeRttDurationMs &&
+ round - minimum_congestion_window_start_round_ >=
+ kProbeRttDurationRounds)
+ EnterProbeBw(now_ms);
+ }
+}
int64_t BbrBweSender::TimeUntilNextProcess() {
return 100;

Powered by Google App Engine
This is Rietveld 408576698