Makes BBR congestion window more similar to QUIC.
This CL makes the congestion window parameters, initial window, minimum window, and maximum window more similar to the values for the implementation in QUIC. It also contains minor behavioral changes to better match the Quic implementation. Bug: webrtc:8415 Change-Id: I26f4b35b6cbb00178ea47a4aee871b1b700c153b Reviewed-on: https://webrtc-review.googlesource.com/83587 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23630}
This commit is contained in:

committed by
Commit Bot

parent
fb4d66be97
commit
5c43150cb0
@ -42,9 +42,6 @@ const DataSize kMaxPacketSize = DataSize::bytes(1452);
|
||||
const DataSize kDefaultTCPMSS = DataSize::bytes(1460);
|
||||
// Constants based on TCP defaults.
|
||||
const DataSize kMaxSegmentSize = kDefaultTCPMSS;
|
||||
// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
|
||||
// Does not inflate the pacing rate.
|
||||
const DataSize kMinimumCongestionWindow = DataSize::bytes(1000);
|
||||
|
||||
// The gain used for the slow start, equal to 2/ln(2).
|
||||
const double kHighGain = 2.885f;
|
||||
@ -72,16 +69,14 @@ const double kStartupGrowthTarget = 1.25;
|
||||
// we don't need to enter PROBE_RTT.
|
||||
const double kSimilarMinRttThreshold = 1.125;
|
||||
|
||||
constexpr int64_t kInitialRttMs = 200;
|
||||
constexpr int64_t kInitialBandwidthKbps = 300;
|
||||
|
||||
constexpr int64_t kMaxRttMs = 1000;
|
||||
constexpr int64_t kMaxBandwidthKbps = 5000;
|
||||
const int64_t kInitialCongestionWindowPackets = 32;
|
||||
// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
|
||||
// Does not inflate the pacing rate.
|
||||
const int64_t kDefaultMinCongestionWindowPackets = 4;
|
||||
const int64_t kDefaultMaxCongestionWindowPackets = 2000;
|
||||
|
||||
constexpr int64_t kInitialCongestionWindowBytes =
|
||||
(kInitialRttMs * kInitialBandwidthKbps) / 8;
|
||||
constexpr int64_t kDefaultMaxCongestionWindowBytes =
|
||||
(kMaxRttMs * kMaxBandwidthKbps) / 8;
|
||||
} // namespace
|
||||
|
||||
BbrNetworkController::BbrControllerConfig
|
||||
@ -179,10 +174,13 @@ BbrNetworkController::BbrNetworkController(NetworkControllerConfig config)
|
||||
min_rtt_(TimeDelta::Zero()),
|
||||
last_rtt_(TimeDelta::Zero()),
|
||||
min_rtt_timestamp_(Timestamp::ms(0)),
|
||||
congestion_window_(DataSize::bytes(kInitialCongestionWindowBytes)),
|
||||
initial_congestion_window_(
|
||||
DataSize::bytes(kInitialCongestionWindowBytes)),
|
||||
max_congestion_window_(DataSize::bytes(kDefaultMaxCongestionWindowBytes)),
|
||||
congestion_window_(kInitialCongestionWindowPackets * kDefaultTCPMSS),
|
||||
initial_congestion_window_(kInitialCongestionWindowPackets *
|
||||
kDefaultTCPMSS),
|
||||
min_congestion_window_(kDefaultMinCongestionWindowPackets *
|
||||
kDefaultTCPMSS),
|
||||
max_congestion_window_(kDefaultMaxCongestionWindowPackets *
|
||||
kDefaultTCPMSS),
|
||||
pacing_rate_(DataRate::Zero()),
|
||||
pacing_gain_(1),
|
||||
congestion_window_gain_constant_(kProbeBWCongestionWindowGain),
|
||||
@ -192,6 +190,7 @@ BbrNetworkController::BbrNetworkController(NetworkControllerConfig config)
|
||||
is_at_full_bandwidth_(false),
|
||||
rounds_without_bandwidth_gain_(0),
|
||||
bandwidth_at_last_round_(DataRate::Zero()),
|
||||
exiting_quiescence_(false),
|
||||
exit_probe_rtt_at_(),
|
||||
probe_rtt_round_passed_(false),
|
||||
last_sample_is_app_limited_(false),
|
||||
@ -206,12 +205,6 @@ BbrNetworkController::BbrNetworkController(NetworkControllerConfig config)
|
||||
default_bandwidth_ = config.starting_bandwidth;
|
||||
constraints_ = config.constraints;
|
||||
Reset();
|
||||
if (config_.num_startup_rtts > 0) {
|
||||
EnterStartupMode();
|
||||
} else {
|
||||
is_at_full_bandwidth_ = true;
|
||||
EnterProbeBandwidthMode(constraints_->at_time);
|
||||
}
|
||||
}
|
||||
|
||||
BbrNetworkController::~BbrNetworkController() {}
|
||||
@ -219,8 +212,13 @@ BbrNetworkController::~BbrNetworkController() {}
|
||||
void BbrNetworkController::Reset() {
|
||||
round_trip_count_ = 0;
|
||||
rounds_without_bandwidth_gain_ = 0;
|
||||
is_at_full_bandwidth_ = false;
|
||||
EnterStartupMode();
|
||||
if (config_.num_startup_rtts > 0) {
|
||||
is_at_full_bandwidth_ = false;
|
||||
EnterStartupMode();
|
||||
} else {
|
||||
is_at_full_bandwidth_ = true;
|
||||
EnterProbeBandwidthMode(constraints_->at_time);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkControlUpdate BbrNetworkController::CreateRateUpdate(Timestamp at_time) {
|
||||
@ -323,6 +321,10 @@ bool BbrNetworkController::InSlowStart() const {
|
||||
NetworkControlUpdate BbrNetworkController::OnSentPacket(SentPacket msg) {
|
||||
last_sent_packet_ = msg.sequence_number;
|
||||
|
||||
if (msg.data_in_flight.IsZero() && sampler_->is_app_limited()) {
|
||||
exiting_quiescence_ = true;
|
||||
}
|
||||
|
||||
if (!aggregation_epoch_start_time_) {
|
||||
aggregation_epoch_start_time_ = msg.send_time;
|
||||
}
|
||||
@ -493,14 +495,14 @@ DataSize BbrNetworkController::GetTargetCongestionWindow(double gain) const {
|
||||
congestion_window = gain * initial_congestion_window_;
|
||||
}
|
||||
|
||||
return std::max(congestion_window, kMinimumCongestionWindow);
|
||||
return std::max(congestion_window, min_congestion_window_);
|
||||
}
|
||||
|
||||
DataSize BbrNetworkController::ProbeRttCongestionWindow() const {
|
||||
if (config_.probe_rtt_based_on_bdp) {
|
||||
return GetTargetCongestionWindow(config_.probe_rtt_congestion_window_gain);
|
||||
}
|
||||
return kMinimumCongestionWindow;
|
||||
return min_congestion_window_;
|
||||
}
|
||||
|
||||
void BbrNetworkController::EnterStartupMode() {
|
||||
@ -689,7 +691,7 @@ void BbrNetworkController::MaybeEnterOrExitProbeRtt(
|
||||
const TransportPacketsFeedback& msg,
|
||||
bool is_round_start,
|
||||
bool min_rtt_expired) {
|
||||
if (min_rtt_expired && mode_ != PROBE_RTT) {
|
||||
if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
|
||||
mode_ = PROBE_RTT;
|
||||
pacing_gain_ = 1;
|
||||
// Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
|
||||
@ -723,6 +725,8 @@ void BbrNetworkController::MaybeEnterOrExitProbeRtt(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exiting_quiescence_ = false;
|
||||
}
|
||||
|
||||
void BbrNetworkController::UpdateRecoveryState(int64_t last_acked_packet,
|
||||
@ -758,8 +762,8 @@ void BbrNetworkController::UpdateRecoveryState(int64_t last_acked_packet,
|
||||
RTC_FALLTHROUGH();
|
||||
case GROWTH:
|
||||
// Exit recovery if appropriate.
|
||||
if (!has_losses && end_recovery_at_ &&
|
||||
last_acked_packet > *end_recovery_at_) {
|
||||
if (!has_losses &&
|
||||
(!end_recovery_at_ || last_acked_packet > *end_recovery_at_)) {
|
||||
recovery_state_ = NOT_IN_RECOVERY;
|
||||
}
|
||||
|
||||
@ -865,7 +869,7 @@ void BbrNetworkController::CalculateCongestionWindow(DataSize bytes_acked) {
|
||||
}
|
||||
|
||||
// Enforce the limits on the congestion window.
|
||||
congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow);
|
||||
congestion_window_ = std::max(congestion_window_, min_congestion_window_);
|
||||
congestion_window_ = std::min(congestion_window_, max_congestion_window_);
|
||||
}
|
||||
|
||||
@ -884,7 +888,7 @@ void BbrNetworkController::CalculateRecoveryWindow(DataSize bytes_acked,
|
||||
// Set up the initial recovery window.
|
||||
if (recovery_window_.IsZero()) {
|
||||
recovery_window_ = bytes_in_flight + bytes_acked;
|
||||
recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
|
||||
recovery_window_ = std::max(min_congestion_window_, recovery_window_);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -906,7 +910,7 @@ void BbrNetworkController::CalculateRecoveryWindow(DataSize bytes_acked,
|
||||
// Sanity checks. Ensure that we always allow to send at least
|
||||
// |bytes_acked| in response.
|
||||
recovery_window_ = std::max(recovery_window_, bytes_in_flight + bytes_acked);
|
||||
recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
|
||||
recovery_window_ = std::max(min_congestion_window_, recovery_window_);
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnApplicationLimited(DataSize bytes_in_flight) {
|
||||
|
@ -32,7 +32,6 @@
|
||||
namespace webrtc {
|
||||
namespace bbr {
|
||||
|
||||
typedef int64_t BbrPacketCount;
|
||||
typedef int64_t BbrRoundTripCount;
|
||||
|
||||
// BbrSender implements BBR congestion control algorithm. BBR aims to estimate
|
||||
@ -269,6 +268,9 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
// The initial value of the |congestion_window_|.
|
||||
DataSize initial_congestion_window_;
|
||||
|
||||
// The smallest value the |congestion_window_| can achieve.
|
||||
DataSize min_congestion_window_;
|
||||
|
||||
// The largest value the |congestion_window_| can achieve.
|
||||
DataSize max_congestion_window_;
|
||||
|
||||
@ -300,6 +302,9 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
// The bandwidth compared to which the increase is measured.
|
||||
DataRate bandwidth_at_last_round_;
|
||||
|
||||
// Set to true upon exiting quiescence.
|
||||
bool exiting_quiescence_;
|
||||
|
||||
// Time at which PROBE_RTT has to be exited. Setting it to zero indicates
|
||||
// that the time is yet unknown as the number of packets in flight has not
|
||||
// reached the required value.
|
||||
@ -314,7 +319,7 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
// Current state of recovery.
|
||||
RecoveryState recovery_state_;
|
||||
// Receiving acknowledgement of a packet after |end_recovery_at_| will cause
|
||||
// BBR to exit the recovery mode. An unset value indicates at least one
|
||||
// BBR to exit the recovery mode. A set value indicates at least one
|
||||
// loss has been detected, so it must not be reset.
|
||||
rtc::Optional<int64_t> end_recovery_at_;
|
||||
// A window used to limit the number of bytes in flight during loss recovery.
|
||||
|
Reference in New Issue
Block a user