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

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

Issue 1413193009: Remove the kMaxSegmentSize constant from QUIC's TcpCubicSender and TcpCubicBytesSender and replace … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@106333315
Patch Set: 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
« no previous file with comments | « no previous file | net/quic/congestion_control/tcp_cubic_sender.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {} 52 clock_(clock) {}
54 53
55 TcpCubicBytesSender::~TcpCubicBytesSender() { 54 TcpCubicBytesSender::~TcpCubicBytesSender() {
56 } 55 }
57 56
58 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config, 57 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
59 Perspective perspective) { 58 Perspective perspective) {
60 if (perspective == Perspective::IS_SERVER) { 59 if (perspective == Perspective::IS_SERVER) {
61 if (config.HasReceivedConnectionOptions() && 60 if (config.HasReceivedConnectionOptions() &&
62 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) { 61 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
63 // Initial window experiment. 62 // Initial window experiment.
64 congestion_window_ = 10 * kMaxSegmentSize; 63 congestion_window_ = 10 * kDefaultTCPMSS;
65 } 64 }
66 if (config.HasReceivedConnectionOptions() && 65 if (config.HasReceivedConnectionOptions() &&
67 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) { 66 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
68 // Min CWND experiment. 67 // Min CWND experiment.
69 min_congestion_window_ = kMaxSegmentSize; 68 min_congestion_window_ = kDefaultTCPMSS;
70 } 69 }
71 if (config.HasReceivedConnectionOptions() && 70 if (config.HasReceivedConnectionOptions() &&
72 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) { 71 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
73 // Min CWND of 4 experiment. 72 // Min CWND of 4 experiment.
74 min4_mode_ = true; 73 min4_mode_ = true;
75 min_congestion_window_ = kMaxSegmentSize; 74 min_congestion_window_ = kDefaultTCPMSS;
76 } 75 }
77 } 76 }
78 } 77 }
79 78
80 void TcpCubicBytesSender::ResumeConnectionState( 79 void TcpCubicBytesSender::ResumeConnectionState(
81 const CachedNetworkParameters& cached_network_params, 80 const CachedNetworkParameters& cached_network_params,
82 bool max_bandwidth_resumption) { 81 bool max_bandwidth_resumption) {
83 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( 82 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
84 max_bandwidth_resumption 83 max_bandwidth_resumption
85 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() 84 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
86 : cached_network_params.bandwidth_estimate_bytes_per_second()); 85 : cached_network_params.bandwidth_estimate_bytes_per_second());
87 QuicTime::Delta rtt_ms = 86 QuicTime::Delta rtt_ms =
88 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); 87 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
89 88
90 // Make sure CWND is in appropriate range (in case of bad data). 89 // Make sure CWND is in appropriate range (in case of bad data).
91 QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms); 90 QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms);
92 congestion_window_ = 91 congestion_window_ =
93 max(min(new_congestion_window, kMaxCongestionWindow * kMaxSegmentSize), 92 max(min(new_congestion_window, kMaxCongestionWindow * kDefaultTCPMSS),
94 kMinCongestionWindowForBandwidthResumption * kMaxSegmentSize); 93 kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS);
95 } 94 }
96 95
97 void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) { 96 void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) {
98 num_connections_ = max(1, num_connections); 97 num_connections_ = max(1, num_connections);
99 cubic_.SetNumConnections(num_connections_); 98 cubic_.SetNumConnections(num_connections_);
100 } 99 }
101 100
102 void TcpCubicBytesSender::SetMaxCongestionWindow( 101 void TcpCubicBytesSender::SetMaxCongestionWindow(
103 QuicByteCount max_congestion_window) { 102 QuicByteCount max_congestion_window) {
104 max_congestion_window_ = max_congestion_window; 103 max_congestion_window_ = max_congestion_window;
105 } 104 }
106 105
107 float TcpCubicBytesSender::RenoBeta() const { 106 float TcpCubicBytesSender::RenoBeta() const {
108 // kNConnectionBeta is the backoff factor after loss for our N-connection 107 // kNConnectionBeta is the backoff factor after loss for our N-connection
109 // emulation, which emulates the effective backoff of an ensemble of N 108 // emulation, which emulates the effective backoff of an ensemble of N
110 // TCP-Reno connections on a single loss event. The effective multiplier is 109 // TCP-Reno connections on a single loss event. The effective multiplier is
111 // computed as: 110 // computed as:
112 return (num_connections_ - 1 + kRenoBeta) / num_connections_; 111 return (num_connections_ - 1 + kRenoBeta) / num_connections_;
113 } 112 }
114 113
115 void TcpCubicBytesSender::OnCongestionEvent( 114 void TcpCubicBytesSender::OnCongestionEvent(
116 bool rtt_updated, 115 bool rtt_updated,
117 QuicByteCount bytes_in_flight, 116 QuicByteCount bytes_in_flight,
118 const CongestionVector& acked_packets, 117 const CongestionVector& acked_packets,
119 const CongestionVector& lost_packets) { 118 const CongestionVector& lost_packets) {
120 if (rtt_updated && InSlowStart() && 119 if (rtt_updated && InSlowStart() &&
121 hybrid_slow_start_.ShouldExitSlowStart( 120 hybrid_slow_start_.ShouldExitSlowStart(
122 rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(), 121 rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
123 congestion_window_ / kMaxSegmentSize)) { 122 congestion_window_ / kDefaultTCPMSS)) {
124 slowstart_threshold_ = congestion_window_; 123 slowstart_threshold_ = congestion_window_;
125 } 124 }
126 for (CongestionVector::const_iterator it = lost_packets.begin(); 125 for (CongestionVector::const_iterator it = lost_packets.begin();
127 it != lost_packets.end(); ++it) { 126 it != lost_packets.end(); ++it) {
128 OnPacketLost(it->first, bytes_in_flight); 127 OnPacketLost(it->first, bytes_in_flight);
129 } 128 }
130 for (CongestionVector::const_iterator it = acked_packets.begin(); 129 for (CongestionVector::const_iterator it = acked_packets.begin();
131 it != acked_packets.end(); ++it) { 130 it != acked_packets.end(); ++it) {
132 OnPacketAcked(it->first, it->second, bytes_in_flight); 131 OnPacketAcked(it->first, it->second, bytes_in_flight);
133 } 132 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 return QuicTime::Delta::Zero(); 219 return QuicTime::Delta::Zero();
221 } 220 }
222 if (InRecovery()) { 221 if (InRecovery()) {
223 // PRR is used when in recovery. 222 // PRR is used when in recovery.
224 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, 223 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
225 slowstart_threshold_); 224 slowstart_threshold_);
226 } 225 }
227 if (GetCongestionWindow() > bytes_in_flight) { 226 if (GetCongestionWindow() > bytes_in_flight) {
228 return QuicTime::Delta::Zero(); 227 return QuicTime::Delta::Zero();
229 } 228 }
230 if (min4_mode_ && bytes_in_flight < 4 * kMaxSegmentSize) { 229 if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
231 return QuicTime::Delta::Zero(); 230 return QuicTime::Delta::Zero();
232 } 231 }
233 return QuicTime::Delta::Infinite(); 232 return QuicTime::Delta::Infinite();
234 } 233 }
235 234
236 QuicBandwidth TcpCubicBytesSender::PacingRate() const { 235 QuicBandwidth TcpCubicBytesSender::PacingRate() const {
237 // We pace at twice the rate of the underlying sender's bandwidth estimate 236 // 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 237 // during slow start and 1.25x during congestion avoidance to ensure pacing
239 // doesn't prevent us from filling the window. 238 // doesn't prevent us from filling the window.
240 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); 239 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) { 302 if (FLAGS_reset_cubic_epoch_when_app_limited) {
304 cubic_.OnApplicationLimited(); 303 cubic_.OnApplicationLimited();
305 } 304 }
306 return; 305 return;
307 } 306 }
308 if (congestion_window_ >= max_congestion_window_) { 307 if (congestion_window_ >= max_congestion_window_) {
309 return; 308 return;
310 } 309 }
311 if (InSlowStart()) { 310 if (InSlowStart()) {
312 // TCP slow start, exponential growth, increase by one for each ACK. 311 // TCP slow start, exponential growth, increase by one for each ACK.
313 congestion_window_ += kMaxSegmentSize; 312 congestion_window_ += kDefaultTCPMSS;
314 DVLOG(1) << "Slow start; congestion window: " << congestion_window_ 313 DVLOG(1) << "Slow start; congestion window: " << congestion_window_
315 << " slowstart threshold: " << slowstart_threshold_; 314 << " slowstart threshold: " << slowstart_threshold_;
316 return; 315 return;
317 } 316 }
318 // Congestion avoidance. 317 // Congestion avoidance.
319 if (reno_) { 318 if (reno_) {
320 // Classic Reno congestion avoidance. 319 // Classic Reno congestion avoidance.
321 ++num_acked_packets_; 320 ++num_acked_packets_;
322 // Divide by num_connections to smoothly increase the CWND at a faster rate 321 // Divide by num_connections to smoothly increase the CWND at a faster rate
323 // than conventional Reno. 322 // than conventional Reno.
324 if (num_acked_packets_ * num_connections_ >= 323 if (num_acked_packets_ * num_connections_ >=
325 congestion_window_ / kMaxSegmentSize) { 324 congestion_window_ / kDefaultTCPMSS) {
326 congestion_window_ += kMaxSegmentSize; 325 congestion_window_ += kDefaultTCPMSS;
327 num_acked_packets_ = 0; 326 num_acked_packets_ = 0;
328 } 327 }
329 328
330 DVLOG(1) << "Reno; congestion window: " << congestion_window_ 329 DVLOG(1) << "Reno; congestion window: " << congestion_window_
331 << " slowstart threshold: " << slowstart_threshold_ 330 << " slowstart threshold: " << slowstart_threshold_
332 << " congestion window count: " << num_acked_packets_; 331 << " congestion window count: " << num_acked_packets_;
333 } else { 332 } else {
334 congestion_window_ = 333 congestion_window_ =
335 min(max_congestion_window_, 334 min(max_congestion_window_,
336 cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_, 335 cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
(...skipping 12 matching lines...) Expand all
349 hybrid_slow_start_.Restart(); 348 hybrid_slow_start_.Restart();
350 slowstart_threshold_ = congestion_window_ / 2; 349 slowstart_threshold_ = congestion_window_ / 2;
351 congestion_window_ = min_congestion_window_; 350 congestion_window_ = min_congestion_window_;
352 } 351 }
353 352
354 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const { 353 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const {
355 return reno_ ? kRenoBytes : kCubicBytes; 354 return reno_ ? kRenoBytes : kCubicBytes;
356 } 355 }
357 356
358 } // namespace net 357 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/quic/congestion_control/tcp_cubic_sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698