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

Side by Side Diff: net/quic/congestion_control/tcp_cubic_bytes_sender.cc

Issue 1421853006: Landing Recent QUIC changes until: Fri Oct 30 22:23:58 2015 +0000 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comments Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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/congestion_control/tcp_cubic_bytes_sender.h" 5 #include "net/quic/congestion_control/tcp_cubic_bytes_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "net/quic/congestion_control/prr_sender.h" 9 #include "net/quic/congestion_control/prr_sender.h"
10 #include "net/quic/congestion_control/rtt_stats.h" 10 #include "net/quic/congestion_control/rtt_stats.h"
11 #include "net/quic/crypto/crypto_protocol.h" 11 #include "net/quic/crypto/crypto_protocol.h"
12 #include "net/quic/proto/cached_network_parameters.pb.h" 12 #include "net/quic/proto/cached_network_parameters.pb.h"
13 #include "net/quic/quic_flags.h" 13 #include "net/quic/quic_flags.h"
14 14
15 using std::max; 15 using std::max;
16 using std::min; 16 using std::min;
17 17
18 namespace net { 18 namespace net {
19 19
20 namespace { 20 namespace {
21 // Constants based on TCP defaults. 21 // Constants based on TCP defaults.
22 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a 22 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
23 // fast retransmission. 23 // fast retransmission.
24 const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS; 24 const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
25 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; 25 const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
26 const QuicByteCount kMaxBurstBytes = 3 * kMaxSegmentSize;
27 const float kRenoBeta = 0.7f; // Reno backoff factor. 26 const float kRenoBeta = 0.7f; // Reno backoff factor.
28 const uint32 kDefaultNumConnections = 2; // N-connection emulation. 27 const uint32 kDefaultNumConnections = 2; // N-connection emulation.
29 } // namespace 28 } // namespace
30 29
31 TcpCubicBytesSender::TcpCubicBytesSender( 30 TcpCubicBytesSender::TcpCubicBytesSender(
32 const QuicClock* clock, 31 const QuicClock* clock,
33 const RttStats* rtt_stats, 32 const RttStats* rtt_stats,
34 bool reno, 33 bool reno,
35 QuicPacketCount initial_tcp_congestion_window, 34 QuicPacketCount initial_tcp_congestion_window,
36 QuicPacketCount max_congestion_window, 35 QuicPacketCount max_congestion_window,
37 QuicConnectionStats* stats) 36 QuicConnectionStats* stats)
38 : cubic_(clock), 37 : cubic_(clock),
39 rtt_stats_(rtt_stats), 38 rtt_stats_(rtt_stats),
40 stats_(stats), 39 stats_(stats),
41 reno_(reno), 40 reno_(reno),
42 num_connections_(kDefaultNumConnections), 41 num_connections_(kDefaultNumConnections),
43 num_acked_packets_(0), 42 num_acked_packets_(0),
44 largest_sent_packet_number_(0), 43 largest_sent_packet_number_(0),
45 largest_acked_packet_number_(0), 44 largest_acked_packet_number_(0),
46 largest_sent_at_last_cutback_(0), 45 largest_sent_at_last_cutback_(0),
47 congestion_window_(initial_tcp_congestion_window * kMaxSegmentSize), 46 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
48 min_congestion_window_(kDefaultMinimumCongestionWindow), 47 min_congestion_window_(kDefaultMinimumCongestionWindow),
49 min4_mode_(false), 48 min4_mode_(false),
50 max_congestion_window_(max_congestion_window * kMaxSegmentSize), 49 max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
51 slowstart_threshold_(max_congestion_window * kMaxSegmentSize), 50 slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
52 last_cutback_exited_slowstart_(false), 51 last_cutback_exited_slowstart_(false) {}
53 clock_(clock) {}
54 52
55 TcpCubicBytesSender::~TcpCubicBytesSender() { 53 TcpCubicBytesSender::~TcpCubicBytesSender() {
56 } 54 }
57 55
58 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config, 56 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
59 Perspective perspective) { 57 Perspective perspective) {
60 if (perspective == Perspective::IS_SERVER) { 58 if (perspective == Perspective::IS_SERVER) {
61 if (config.HasReceivedConnectionOptions() && 59 if (config.HasReceivedConnectionOptions() &&
62 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) { 60 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
63 // Initial window experiment. 61 // Initial window experiment.
64 congestion_window_ = 10 * kMaxSegmentSize; 62 congestion_window_ = 10 * kDefaultTCPMSS;
65 } 63 }
66 if (config.HasReceivedConnectionOptions() && 64 if (config.HasReceivedConnectionOptions() &&
67 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) { 65 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
68 // Min CWND experiment. 66 // Min CWND experiment.
69 min_congestion_window_ = kMaxSegmentSize; 67 min_congestion_window_ = kDefaultTCPMSS;
70 } 68 }
71 if (config.HasReceivedConnectionOptions() && 69 if (config.HasReceivedConnectionOptions() &&
72 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) { 70 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
73 // Min CWND of 4 experiment. 71 // Min CWND of 4 experiment.
74 min4_mode_ = true; 72 min4_mode_ = true;
75 min_congestion_window_ = kMaxSegmentSize; 73 min_congestion_window_ = kDefaultTCPMSS;
76 } 74 }
77 } 75 }
78 } 76 }
79 77
80 void TcpCubicBytesSender::ResumeConnectionState( 78 void TcpCubicBytesSender::ResumeConnectionState(
81 const CachedNetworkParameters& cached_network_params, 79 const CachedNetworkParameters& cached_network_params,
82 bool max_bandwidth_resumption) { 80 bool max_bandwidth_resumption) {
83 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( 81 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
84 max_bandwidth_resumption 82 max_bandwidth_resumption
85 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() 83 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
86 : cached_network_params.bandwidth_estimate_bytes_per_second()); 84 : cached_network_params.bandwidth_estimate_bytes_per_second());
87 QuicTime::Delta rtt_ms = 85 QuicTime::Delta rtt_ms =
88 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); 86 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
89 87
90 // Make sure CWND is in appropriate range (in case of bad data). 88 // Make sure CWND is in appropriate range (in case of bad data).
91 QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms); 89 QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms);
92 congestion_window_ = 90 congestion_window_ =
93 max(min(new_congestion_window, kMaxCongestionWindow * kMaxSegmentSize), 91 max(min(new_congestion_window, kMaxCongestionWindow * kDefaultTCPMSS),
94 kMinCongestionWindowForBandwidthResumption * kMaxSegmentSize); 92 kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS);
95 } 93 }
96 94
97 void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) { 95 void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) {
98 num_connections_ = max(1, num_connections); 96 num_connections_ = max(1, num_connections);
99 cubic_.SetNumConnections(num_connections_); 97 cubic_.SetNumConnections(num_connections_);
100 } 98 }
101 99
102 void TcpCubicBytesSender::SetMaxCongestionWindow( 100 void TcpCubicBytesSender::SetMaxCongestionWindow(
103 QuicByteCount max_congestion_window) { 101 QuicByteCount max_congestion_window) {
104 max_congestion_window_ = max_congestion_window; 102 max_congestion_window_ = max_congestion_window;
105 } 103 }
106 104
107 float TcpCubicBytesSender::RenoBeta() const { 105 float TcpCubicBytesSender::RenoBeta() const {
108 // kNConnectionBeta is the backoff factor after loss for our N-connection 106 // kNConnectionBeta is the backoff factor after loss for our N-connection
109 // emulation, which emulates the effective backoff of an ensemble of N 107 // emulation, which emulates the effective backoff of an ensemble of N
110 // TCP-Reno connections on a single loss event. The effective multiplier is 108 // TCP-Reno connections on a single loss event. The effective multiplier is
111 // computed as: 109 // computed as:
112 return (num_connections_ - 1 + kRenoBeta) / num_connections_; 110 return (num_connections_ - 1 + kRenoBeta) / num_connections_;
113 } 111 }
114 112
115 void TcpCubicBytesSender::OnCongestionEvent( 113 void TcpCubicBytesSender::OnCongestionEvent(
116 bool rtt_updated, 114 bool rtt_updated,
117 QuicByteCount bytes_in_flight, 115 QuicByteCount bytes_in_flight,
118 const CongestionVector& acked_packets, 116 const CongestionVector& acked_packets,
119 const CongestionVector& lost_packets) { 117 const CongestionVector& lost_packets) {
120 if (rtt_updated && InSlowStart() && 118 if (rtt_updated && InSlowStart() &&
121 hybrid_slow_start_.ShouldExitSlowStart( 119 hybrid_slow_start_.ShouldExitSlowStart(
122 rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(), 120 rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
123 congestion_window_ / kMaxSegmentSize)) { 121 congestion_window_ / kDefaultTCPMSS)) {
124 slowstart_threshold_ = congestion_window_; 122 slowstart_threshold_ = congestion_window_;
125 } 123 }
126 for (CongestionVector::const_iterator it = lost_packets.begin(); 124 for (CongestionVector::const_iterator it = lost_packets.begin();
127 it != lost_packets.end(); ++it) { 125 it != lost_packets.end(); ++it) {
128 OnPacketLost(it->first, bytes_in_flight); 126 OnPacketLost(it->first, bytes_in_flight);
129 } 127 }
130 for (CongestionVector::const_iterator it = acked_packets.begin(); 128 for (CongestionVector::const_iterator it = acked_packets.begin();
131 it != acked_packets.end(); ++it) { 129 it != acked_packets.end(); ++it) {
132 OnPacketAcked(it->first, it->second, bytes_in_flight); 130 OnPacketAcked(it->first, it->second, bytes_in_flight);
133 } 131 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 return QuicTime::Delta::Zero(); 218 return QuicTime::Delta::Zero();
221 } 219 }
222 if (InRecovery()) { 220 if (InRecovery()) {
223 // PRR is used when in recovery. 221 // PRR is used when in recovery.
224 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, 222 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
225 slowstart_threshold_); 223 slowstart_threshold_);
226 } 224 }
227 if (GetCongestionWindow() > bytes_in_flight) { 225 if (GetCongestionWindow() > bytes_in_flight) {
228 return QuicTime::Delta::Zero(); 226 return QuicTime::Delta::Zero();
229 } 227 }
230 if (min4_mode_ && bytes_in_flight < 4 * kMaxSegmentSize) { 228 if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
231 return QuicTime::Delta::Zero(); 229 return QuicTime::Delta::Zero();
232 } 230 }
233 return QuicTime::Delta::Infinite(); 231 return QuicTime::Delta::Infinite();
234 } 232 }
235 233
236 QuicBandwidth TcpCubicBytesSender::PacingRate() const { 234 QuicBandwidth TcpCubicBytesSender::PacingRate() const {
237 // We pace at twice the rate of the underlying sender's bandwidth estimate 235 // We pace at twice the rate of the underlying sender's bandwidth estimate
238 // during slow start and 1.25x during congestion avoidance to ensure pacing 236 // during slow start and 1.25x during congestion avoidance to ensure pacing
239 // doesn't prevent us from filling the window. 237 // doesn't prevent us from filling the window.
240 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); 238 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (FLAGS_reset_cubic_epoch_when_app_limited) { 301 if (FLAGS_reset_cubic_epoch_when_app_limited) {
304 cubic_.OnApplicationLimited(); 302 cubic_.OnApplicationLimited();
305 } 303 }
306 return; 304 return;
307 } 305 }
308 if (congestion_window_ >= max_congestion_window_) { 306 if (congestion_window_ >= max_congestion_window_) {
309 return; 307 return;
310 } 308 }
311 if (InSlowStart()) { 309 if (InSlowStart()) {
312 // TCP slow start, exponential growth, increase by one for each ACK. 310 // TCP slow start, exponential growth, increase by one for each ACK.
313 congestion_window_ += kMaxSegmentSize; 311 congestion_window_ += kDefaultTCPMSS;
314 DVLOG(1) << "Slow start; congestion window: " << congestion_window_ 312 DVLOG(1) << "Slow start; congestion window: " << congestion_window_
315 << " slowstart threshold: " << slowstart_threshold_; 313 << " slowstart threshold: " << slowstart_threshold_;
316 return; 314 return;
317 } 315 }
318 // Congestion avoidance. 316 // Congestion avoidance.
319 if (reno_) { 317 if (reno_) {
320 // Classic Reno congestion avoidance. 318 // Classic Reno congestion avoidance.
321 ++num_acked_packets_; 319 ++num_acked_packets_;
322 // Divide by num_connections to smoothly increase the CWND at a faster rate 320 // Divide by num_connections to smoothly increase the CWND at a faster rate
323 // than conventional Reno. 321 // than conventional Reno.
324 if (num_acked_packets_ * num_connections_ >= 322 if (num_acked_packets_ * num_connections_ >=
325 congestion_window_ / kMaxSegmentSize) { 323 congestion_window_ / kDefaultTCPMSS) {
326 congestion_window_ += kMaxSegmentSize; 324 congestion_window_ += kDefaultTCPMSS;
327 num_acked_packets_ = 0; 325 num_acked_packets_ = 0;
328 } 326 }
329 327
330 DVLOG(1) << "Reno; congestion window: " << congestion_window_ 328 DVLOG(1) << "Reno; congestion window: " << congestion_window_
331 << " slowstart threshold: " << slowstart_threshold_ 329 << " slowstart threshold: " << slowstart_threshold_
332 << " congestion window count: " << num_acked_packets_; 330 << " congestion window count: " << num_acked_packets_;
333 } else { 331 } else {
334 congestion_window_ = 332 congestion_window_ =
335 min(max_congestion_window_, 333 min(max_congestion_window_,
336 cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_, 334 cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
(...skipping 12 matching lines...) Expand all
349 hybrid_slow_start_.Restart(); 347 hybrid_slow_start_.Restart();
350 slowstart_threshold_ = congestion_window_ / 2; 348 slowstart_threshold_ = congestion_window_ / 2;
351 congestion_window_ = min_congestion_window_; 349 congestion_window_ = min_congestion_window_;
352 } 350 }
353 351
354 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const { 352 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const {
355 return reno_ ? kRenoBytes : kCubicBytes; 353 return reno_ ? kRenoBytes : kCubicBytes;
356 } 354 }
357 355
358 } // namespace net 356 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/tcp_cubic_bytes_sender.h ('k') | net/quic/congestion_control/tcp_cubic_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698