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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 QuicRandom* random) | 73 QuicRandom* random) |
74 : rtt_stats_(rtt_stats), | 74 : rtt_stats_(rtt_stats), |
75 unacked_packets_(unacked_packets), | 75 unacked_packets_(unacked_packets), |
76 random_(random), | 76 random_(random), |
77 mode_(STARTUP), | 77 mode_(STARTUP), |
78 sampler_(), | 78 sampler_(), |
79 round_trip_count_(0), | 79 round_trip_count_(0), |
80 last_sent_packet_(0), | 80 last_sent_packet_(0), |
81 current_round_trip_end_(0), | 81 current_round_trip_end_(0), |
82 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), | 82 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), |
83 max_ack_spacing_(kBandwidthWindowSize, QuicTime::Delta::Zero(), 0), | |
84 largest_acked_time_(QuicTime::Zero()), | |
85 largest_acked_sent_time_(QuicTime::Zero()), | |
86 max_ack_height_(kBandwidthWindowSize, 0, 0), | 83 max_ack_height_(kBandwidthWindowSize, 0, 0), |
87 aggregation_epoch_start_time_(QuicTime::Zero()), | 84 aggregation_epoch_start_time_(QuicTime::Zero()), |
88 aggregation_epoch_bytes_(0), | 85 aggregation_epoch_bytes_(0), |
89 min_rtt_(QuicTime::Delta::Zero()), | 86 min_rtt_(QuicTime::Delta::Zero()), |
90 min_rtt_timestamp_(QuicTime::Zero()), | 87 min_rtt_timestamp_(QuicTime::Zero()), |
91 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), | 88 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), |
92 initial_congestion_window_(initial_tcp_congestion_window * | 89 initial_congestion_window_(initial_tcp_congestion_window * |
93 kDefaultTCPMSS), | 90 kDefaultTCPMSS), |
94 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), | 91 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), |
95 pacing_rate_(QuicBandwidth::Zero()), | 92 pacing_rate_(QuicBandwidth::Zero()), |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 240 |
244 DiscardLostPackets(lost_packets); | 241 DiscardLostPackets(lost_packets); |
245 | 242 |
246 // Input the new data into the BBR model of the connection. | 243 // Input the new data into the BBR model of the connection. |
247 if (!acked_packets.empty()) { | 244 if (!acked_packets.empty()) { |
248 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; | 245 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; |
249 is_round_start = UpdateRoundTripCounter(last_acked_packet); | 246 is_round_start = UpdateRoundTripCounter(last_acked_packet); |
250 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); | 247 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); |
251 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), | 248 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), |
252 is_round_start); | 249 is_round_start); |
253 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2) { | |
254 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 1, 2); | |
255 UpdateAckSpacing(event_time, last_acked_packet, acked_packets); | |
256 } | |
257 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { | 250 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { |
258 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, | 251 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, |
259 2); | 252 2); |
260 UpdateAckAggregationBytes( | 253 UpdateAckAggregationBytes( |
261 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); | 254 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); |
262 } | 255 } |
263 } | 256 } |
264 | 257 |
265 // Handle logic specific to PROBE_BW mode. | 258 // Handle logic specific to PROBE_BW mode. |
266 if (mode_ == PROBE_BW) { | 259 if (mode_ == PROBE_BW) { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 | 513 |
521 case GROWTH: | 514 case GROWTH: |
522 // Exit recovery if appropriate. | 515 // Exit recovery if appropriate. |
523 if (!has_losses && last_acked_packet > end_recovery_at_) { | 516 if (!has_losses && last_acked_packet > end_recovery_at_) { |
524 recovery_state_ = NOT_IN_RECOVERY; | 517 recovery_state_ = NOT_IN_RECOVERY; |
525 } | 518 } |
526 break; | 519 break; |
527 } | 520 } |
528 } | 521 } |
529 | 522 |
530 // TODO(ianswett): Move this logic into BandwidthSampler. | |
531 void BbrSender::UpdateAckSpacing(QuicTime ack_time, | |
532 QuicPacketNumber largest_newly_acked, | |
533 const CongestionVector& acked_packets) { | |
534 // Ignore acks of reordered packets. | |
535 if (largest_newly_acked < unacked_packets_->largest_observed()) { | |
536 return; | |
537 } | |
538 // Ignore acks of only one packet to filter out delayed acks. | |
539 if (acked_packets.size() == 1) { | |
540 return; | |
541 } | |
542 QuicTime largest_newly_acked_sent_time = | |
543 unacked_packets_->GetTransmissionInfo(largest_newly_acked).sent_time; | |
544 // Initialize on the first ack. | |
545 if (!largest_acked_time_.IsInitialized()) { | |
546 largest_acked_time_ = ack_time; | |
547 largest_acked_sent_time_ = largest_newly_acked_sent_time; | |
548 return; | |
549 } | |
550 QuicTime::Delta ack_delta = ack_time - largest_acked_time_; | |
551 QuicTime::Delta send_delta = | |
552 largest_newly_acked_sent_time - largest_acked_sent_time_; | |
553 largest_acked_time_ = ack_time; | |
554 largest_acked_sent_time_ = largest_newly_acked_sent_time; | |
555 if (ack_delta <= send_delta) { | |
556 return; | |
557 } | |
558 | |
559 // Limit the ack spacing to SRTT to filter outliers. | |
560 QuicTime::Delta ack_spacing = | |
561 std::min(ack_delta - send_delta, rtt_stats_->smoothed_rtt()); | |
562 max_ack_spacing_.Update(ack_spacing, round_trip_count_); | |
563 } | |
564 | |
565 // TODO(ianswett): Move this logic into BandwidthSampler. | |
566 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, | 523 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, |
567 QuicByteCount newly_acked_bytes) { | 524 QuicByteCount newly_acked_bytes) { |
568 // Compute how many bytes are expected to be delivered, assuming max bandwidth | 525 // Compute how many bytes are expected to be delivered, assuming max bandwidth |
569 // is correct. | 526 // is correct. |
570 QuicByteCount expected_bytes_acked = | 527 QuicByteCount expected_bytes_acked = |
571 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); | 528 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); |
572 // Reset the current aggregation epoch as soon as the ack arrival rate is less | 529 // Reset the current aggregation epoch as soon as the ack arrival rate is less |
573 // than or equal to the max bandwidth. | 530 // than or equal to the max bandwidth. |
574 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { | 531 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { |
575 // Reset to start measuring a new aggregation epoch. | 532 // Reset to start measuring a new aggregation epoch. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 if (mode_ == PROBE_RTT) { | 569 if (mode_ == PROBE_RTT) { |
613 return; | 570 return; |
614 } | 571 } |
615 | 572 |
616 QuicByteCount target_window = | 573 QuicByteCount target_window = |
617 GetTargetCongestionWindow(congestion_window_gain_); | 574 GetTargetCongestionWindow(congestion_window_gain_); |
618 | 575 |
619 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { | 576 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { |
620 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * | 577 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * |
621 BandwidthEstimate(); | 578 BandwidthEstimate(); |
622 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2 && | |
623 is_at_full_bandwidth_) { | |
624 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 2, 2); | |
625 // Add CWND for inter-ack spacing once STARTUP has been exited. | |
626 target_window += max_ack_spacing_.GetBest() * BandwidthEstimate(); | |
627 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes && | 579 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes && |
628 is_at_full_bandwidth_) { | 580 is_at_full_bandwidth_) { |
629 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2, | 581 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2, |
630 2); | 582 2); |
631 target_window += max_ack_height_.GetBest(); | 583 target_window += max_ack_height_.GetBest(); |
632 } | 584 } |
633 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) { | 585 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) { |
634 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so | 586 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so |
635 // allow extra CWND to make QUIC's BBR CWND identical to TCP's. | 587 // allow extra CWND to make QUIC's BBR CWND identical to TCP's. |
636 QuicByteCount tso_segs_goal = 0; | 588 QuicByteCount tso_segs_goal = 0; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() | 689 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() |
738 << std::endl; | 690 << std::endl; |
739 | 691 |
740 os << "Last sample is app-limited: " | 692 os << "Last sample is app-limited: " |
741 << (state.last_sample_is_app_limited ? "yes" : "no"); | 693 << (state.last_sample_is_app_limited ? "yes" : "no"); |
742 | 694 |
743 return os; | 695 return os; |
744 } | 696 } |
745 | 697 |
746 } // namespace net | 698 } // namespace net |
OLD | NEW |