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