OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/core/congestion_control/bbr_sender.h" | 5 #include "net/quic/core/congestion_control/bbr_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "net/quic/core/congestion_control/rtt_stats.h" | 10 #include "net/quic/core/congestion_control/rtt_stats.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 random_(random), | 75 random_(random), |
76 mode_(STARTUP), | 76 mode_(STARTUP), |
77 sampler_(), | 77 sampler_(), |
78 round_trip_count_(0), | 78 round_trip_count_(0), |
79 last_sent_packet_(0), | 79 last_sent_packet_(0), |
80 current_round_trip_end_(0), | 80 current_round_trip_end_(0), |
81 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), | 81 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), |
82 max_ack_spacing_(kBandwidthWindowSize, QuicTime::Delta::Zero(), 0), | 82 max_ack_spacing_(kBandwidthWindowSize, QuicTime::Delta::Zero(), 0), |
83 largest_acked_time_(QuicTime::Zero()), | 83 largest_acked_time_(QuicTime::Zero()), |
84 largest_acked_sent_time_(QuicTime::Zero()), | 84 largest_acked_sent_time_(QuicTime::Zero()), |
| 85 max_ack_height_(kBandwidthWindowSize, 0, 0), |
| 86 aggregation_epoch_start_time_(QuicTime::Zero()), |
| 87 aggregation_epoch_bytes_(0), |
85 min_rtt_(QuicTime::Delta::Zero()), | 88 min_rtt_(QuicTime::Delta::Zero()), |
86 min_rtt_timestamp_(QuicTime::Zero()), | 89 min_rtt_timestamp_(QuicTime::Zero()), |
87 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), | 90 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), |
88 initial_congestion_window_(initial_tcp_congestion_window * | 91 initial_congestion_window_(initial_tcp_congestion_window * |
89 kDefaultTCPMSS), | 92 kDefaultTCPMSS), |
90 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), | 93 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), |
91 pacing_rate_(QuicBandwidth::Zero()), | 94 pacing_rate_(QuicBandwidth::Zero()), |
92 pacing_gain_(1), | 95 pacing_gain_(1), |
93 congestion_window_gain_(1), | 96 congestion_window_gain_(1), |
94 congestion_window_gain_constant_( | 97 congestion_window_gain_constant_( |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 if (!acked_packets.empty()) { | 205 if (!acked_packets.empty()) { |
203 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; | 206 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; |
204 is_round_start = UpdateRoundTripCounter(last_acked_packet); | 207 is_round_start = UpdateRoundTripCounter(last_acked_packet); |
205 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); | 208 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); |
206 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), | 209 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), |
207 is_round_start); | 210 is_round_start); |
208 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2) { | 211 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2) { |
209 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 1, 2); | 212 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 1, 2); |
210 UpdateAckSpacing(event_time, last_acked_packet, acked_packets); | 213 UpdateAckSpacing(event_time, last_acked_packet, acked_packets); |
211 } | 214 } |
| 215 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { |
| 216 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, |
| 217 2); |
| 218 UpdateAckAggregationBytes( |
| 219 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); |
| 220 } |
212 } | 221 } |
213 | 222 |
214 // Handle logic specific to PROBE_BW mode. | 223 // Handle logic specific to PROBE_BW mode. |
215 if (mode_ == PROBE_BW) { | 224 if (mode_ == PROBE_BW) { |
216 UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty()); | 225 UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty()); |
217 } | 226 } |
218 | 227 |
219 // Handle logic specific to STARTUP and DRAIN modes. | 228 // Handle logic specific to STARTUP and DRAIN modes. |
220 if (is_round_start && !is_at_full_bandwidth_) { | 229 if (is_round_start && !is_at_full_bandwidth_) { |
221 CheckIfFullBandwidthReached(); | 230 CheckIfFullBandwidthReached(); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 if (ack_delta <= send_delta) { | 510 if (ack_delta <= send_delta) { |
502 return; | 511 return; |
503 } | 512 } |
504 | 513 |
505 // Limit the ack spacing to SRTT to filter outliers. | 514 // Limit the ack spacing to SRTT to filter outliers. |
506 QuicTime::Delta ack_spacing = | 515 QuicTime::Delta ack_spacing = |
507 std::min(ack_delta - send_delta, rtt_stats_->smoothed_rtt()); | 516 std::min(ack_delta - send_delta, rtt_stats_->smoothed_rtt()); |
508 max_ack_spacing_.Update(ack_spacing, round_trip_count_); | 517 max_ack_spacing_.Update(ack_spacing, round_trip_count_); |
509 } | 518 } |
510 | 519 |
| 520 // TODO(ianswett): Move this logic into BandwidthSampler. |
| 521 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, |
| 522 QuicByteCount newly_acked_bytes) { |
| 523 // Compute how many bytes are expected to be delivered, assuming max bandwidth |
| 524 // is correct. |
| 525 QuicByteCount expected_bytes_acked = |
| 526 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); |
| 527 // Reset the current aggregation epoch as soon as the ack arrival rate is less |
| 528 // than or equal to the max bandwidth. |
| 529 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { |
| 530 // Reset to start measuring a new aggregation epoch. |
| 531 aggregation_epoch_bytes_ = newly_acked_bytes; |
| 532 aggregation_epoch_start_time_ = ack_time; |
| 533 return; |
| 534 } |
| 535 |
| 536 // Compute how many extra bytes were delivered vs max bandwidth. |
| 537 // Include the bytes most recently acknowledged to account for stretch acks. |
| 538 aggregation_epoch_bytes_ += newly_acked_bytes; |
| 539 max_ack_height_.Update(aggregation_epoch_bytes_ - expected_bytes_acked, |
| 540 round_trip_count_); |
| 541 } |
| 542 |
511 void BbrSender::CalculatePacingRate() { | 543 void BbrSender::CalculatePacingRate() { |
512 if (BandwidthEstimate().IsZero()) { | 544 if (BandwidthEstimate().IsZero()) { |
513 return; | 545 return; |
514 } | 546 } |
515 | 547 |
516 QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate(); | 548 QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate(); |
517 if (is_at_full_bandwidth_) { | 549 if (is_at_full_bandwidth_) { |
518 pacing_rate_ = target_rate; | 550 pacing_rate_ = target_rate; |
519 return; | 551 return; |
520 } | 552 } |
(...skipping 19 matching lines...) Expand all Loading... |
540 GetTargetCongestionWindow(congestion_window_gain_); | 572 GetTargetCongestionWindow(congestion_window_gain_); |
541 | 573 |
542 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { | 574 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { |
543 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * | 575 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * |
544 BandwidthEstimate(); | 576 BandwidthEstimate(); |
545 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2 && | 577 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2 && |
546 is_at_full_bandwidth_) { | 578 is_at_full_bandwidth_) { |
547 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 2, 2); | 579 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 2, 2); |
548 // Add CWND for inter-ack spacing once STARTUP has been exited. | 580 // Add CWND for inter-ack spacing once STARTUP has been exited. |
549 target_window += max_ack_spacing_.GetBest() * BandwidthEstimate(); | 581 target_window += max_ack_spacing_.GetBest() * BandwidthEstimate(); |
| 582 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes && |
| 583 is_at_full_bandwidth_) { |
| 584 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2, |
| 585 2); |
| 586 target_window += max_ack_height_.GetBest(); |
550 } | 587 } |
551 | 588 |
552 // Instead of immediately setting the target CWND as the new one, BBR grows | 589 // Instead of immediately setting the target CWND as the new one, BBR grows |
553 // the CWND towards |target_window| by only increasing it |bytes_acked| at a | 590 // the CWND towards |target_window| by only increasing it |bytes_acked| at a |
554 // time. | 591 // time. |
555 if (is_at_full_bandwidth_) { | 592 if (is_at_full_bandwidth_) { |
556 congestion_window_ = | 593 congestion_window_ = |
557 std::min(target_window, congestion_window_ + bytes_acked); | 594 std::min(target_window, congestion_window_ + bytes_acked); |
558 } else if (congestion_window_ < target_window || | 595 } else if (congestion_window_ < target_window || |
559 sampler_.total_bytes_acked() < initial_congestion_window_) { | 596 sampler_.total_bytes_acked() < initial_congestion_window_) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() | 677 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() |
641 << std::endl; | 678 << std::endl; |
642 | 679 |
643 os << "Last sample is app-limited: " | 680 os << "Last sample is app-limited: " |
644 << (state.last_sample_is_app_limited ? "yes" : "no"); | 681 << (state.last_sample_is_app_limited ? "yes" : "no"); |
645 | 682 |
646 return os; | 683 return os; |
647 } | 684 } |
648 | 685 |
649 } // namespace net | 686 } // namespace net |
OLD | NEW |