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

Side by Side Diff: net/quic/congestion_control/tcp_cubic_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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_sender.h" 5 #include "net/quic/congestion_control/tcp_cubic_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "net/quic/congestion_control/prr_sender.h" 10 #include "net/quic/congestion_control/prr_sender.h"
11 #include "net/quic/congestion_control/rtt_stats.h" 11 #include "net/quic/congestion_control/rtt_stats.h"
12 #include "net/quic/crypto/crypto_protocol.h" 12 #include "net/quic/crypto/crypto_protocol.h"
13 #include "net/quic/proto/cached_network_parameters.pb.h" 13 #include "net/quic/proto/cached_network_parameters.pb.h"
14 #include "net/quic/quic_flags.h" 14 #include "net/quic/quic_flags.h"
15 15
16 using std::max; 16 using std::max;
17 using std::min; 17 using std::min;
18 18
19 namespace net { 19 namespace net {
20 20
21 namespace { 21 namespace {
22 // Constants based on TCP defaults. 22 // Constants based on TCP defaults.
23 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a 23 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
24 // fast retransmission. The cwnd after a timeout is still 1. 24 // fast retransmission. The cwnd after a timeout is still 1.
25 const QuicPacketCount kDefaultMinimumCongestionWindow = 2; 25 const QuicPacketCount kDefaultMinimumCongestionWindow = 2;
26 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; 26 const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
27 const QuicByteCount kMaxBurstBytes = 3 * kMaxSegmentSize;
28 const float kRenoBeta = 0.7f; // Reno backoff factor. 27 const float kRenoBeta = 0.7f; // Reno backoff factor.
29 const uint32 kDefaultNumConnections = 2; // N-connection emulation. 28 const uint32 kDefaultNumConnections = 2; // N-connection emulation.
30 } // namespace 29 } // namespace
31 30
32 TcpCubicSender::TcpCubicSender(const QuicClock* clock, 31 TcpCubicSender::TcpCubicSender(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_tcp_congestion_window, 35 QuicPacketCount max_tcp_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 congestion_window_count_(0), 42 congestion_window_count_(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), 46 congestion_window_(initial_tcp_congestion_window),
48 min_congestion_window_(kDefaultMinimumCongestionWindow), 47 min_congestion_window_(kDefaultMinimumCongestionWindow),
49 min4_mode_(false), 48 min4_mode_(false),
50 slowstart_threshold_(max_tcp_congestion_window), 49 slowstart_threshold_(max_tcp_congestion_window),
51 last_cutback_exited_slowstart_(false), 50 last_cutback_exited_slowstart_(false),
52 max_tcp_congestion_window_(max_tcp_congestion_window), 51 max_tcp_congestion_window_(max_tcp_congestion_window) {}
53 clock_(clock) {}
54 52
55 TcpCubicSender::~TcpCubicSender() { 53 TcpCubicSender::~TcpCubicSender() {
56 UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_); 54 UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_);
57 } 55 }
58 56
59 void TcpCubicSender::SetFromConfig(const QuicConfig& config, 57 void TcpCubicSender::SetFromConfig(const QuicConfig& config,
60 Perspective perspective) { 58 Perspective perspective) {
61 if (perspective == Perspective::IS_SERVER) { 59 if (perspective == Perspective::IS_SERVER) {
62 if (config.HasReceivedConnectionOptions() && 60 if (config.HasReceivedConnectionOptions() &&
63 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) { 61 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 bool max_bandwidth_resumption) { 96 bool max_bandwidth_resumption) {
99 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( 97 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
100 max_bandwidth_resumption 98 max_bandwidth_resumption
101 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() 99 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
102 : cached_network_params.bandwidth_estimate_bytes_per_second()); 100 : cached_network_params.bandwidth_estimate_bytes_per_second());
103 QuicTime::Delta rtt_ms = 101 QuicTime::Delta rtt_ms =
104 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); 102 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
105 103
106 // Make sure CWND is in appropriate range (in case of bad data). 104 // Make sure CWND is in appropriate range (in case of bad data).
107 QuicPacketCount new_congestion_window = 105 QuicPacketCount new_congestion_window =
108 bandwidth.ToBytesPerPeriod(rtt_ms) / kMaxPacketSize; 106 bandwidth.ToBytesPerPeriod(rtt_ms) / kDefaultTCPMSS;
109 congestion_window_ = max(min(new_congestion_window, kMaxCongestionWindow), 107 congestion_window_ = max(min(new_congestion_window, kMaxCongestionWindow),
110 kMinCongestionWindowForBandwidthResumption); 108 kMinCongestionWindowForBandwidthResumption);
111 } 109 }
112 110
113 void TcpCubicSender::SetNumEmulatedConnections(int num_connections) { 111 void TcpCubicSender::SetNumEmulatedConnections(int num_connections) {
114 num_connections_ = max(1, num_connections); 112 num_connections_ = max(1, num_connections);
115 cubic_.SetNumConnections(num_connections_); 113 cubic_.SetNumConnections(num_connections_);
116 } 114 }
117 115
118 void TcpCubicSender::SetMaxCongestionWindow( 116 void TcpCubicSender::SetMaxCongestionWindow(
119 QuicByteCount max_congestion_window) { 117 QuicByteCount max_congestion_window) {
120 max_tcp_congestion_window_ = max_congestion_window / kMaxPacketSize; 118 max_tcp_congestion_window_ = max_congestion_window / kDefaultTCPMSS;
121 } 119 }
122 120
123 float TcpCubicSender::RenoBeta() const { 121 float TcpCubicSender::RenoBeta() const {
124 // kNConnectionBeta is the backoff factor after loss for our N-connection 122 // kNConnectionBeta is the backoff factor after loss for our N-connection
125 // emulation, which emulates the effective backoff of an ensemble of N 123 // emulation, which emulates the effective backoff of an ensemble of N
126 // TCP-Reno connections on a single loss event. The effective multiplier is 124 // TCP-Reno connections on a single loss event. The effective multiplier is
127 // computed as: 125 // computed as:
128 return (num_connections_ - 1 + kRenoBeta) / num_connections_; 126 return (num_connections_ - 1 + kRenoBeta) / num_connections_;
129 } 127 }
130 128
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 QuicTime /* now */, 228 QuicTime /* now */,
231 QuicByteCount bytes_in_flight, 229 QuicByteCount bytes_in_flight,
232 HasRetransmittableData has_retransmittable_data) const { 230 HasRetransmittableData has_retransmittable_data) const {
233 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { 231 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
234 // For TCP we can always send an ACK immediately. 232 // For TCP we can always send an ACK immediately.
235 return QuicTime::Delta::Zero(); 233 return QuicTime::Delta::Zero();
236 } 234 }
237 if (InRecovery()) { 235 if (InRecovery()) {
238 // PRR is used when in recovery. 236 // PRR is used when in recovery.
239 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, 237 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
240 slowstart_threshold_ * kMaxSegmentSize); 238 slowstart_threshold_ * kDefaultTCPMSS);
241 } 239 }
242 if (GetCongestionWindow() > bytes_in_flight) { 240 if (GetCongestionWindow() > bytes_in_flight) {
243 return QuicTime::Delta::Zero(); 241 return QuicTime::Delta::Zero();
244 } 242 }
245 if (min4_mode_ && bytes_in_flight < 4 * kMaxSegmentSize) { 243 if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
246 return QuicTime::Delta::Zero(); 244 return QuicTime::Delta::Zero();
247 } 245 }
248 return QuicTime::Delta::Infinite(); 246 return QuicTime::Delta::Infinite();
249 } 247 }
250 248
251 QuicBandwidth TcpCubicSender::PacingRate() const { 249 QuicBandwidth TcpCubicSender::PacingRate() const {
252 // We pace at twice the rate of the underlying sender's bandwidth estimate 250 // We pace at twice the rate of the underlying sender's bandwidth estimate
253 // during slow start and 1.25x during congestion avoidance to ensure pacing 251 // during slow start and 1.25x during congestion avoidance to ensure pacing
254 // doesn't prevent us from filling the window. 252 // doesn't prevent us from filling the window.
255 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); 253 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
(...skipping 16 matching lines...) Expand all
272 270
273 QuicTime::Delta TcpCubicSender::RetransmissionDelay() const { 271 QuicTime::Delta TcpCubicSender::RetransmissionDelay() const {
274 if (rtt_stats_->smoothed_rtt().IsZero()) { 272 if (rtt_stats_->smoothed_rtt().IsZero()) {
275 return QuicTime::Delta::Zero(); 273 return QuicTime::Delta::Zero();
276 } 274 }
277 return rtt_stats_->smoothed_rtt().Add( 275 return rtt_stats_->smoothed_rtt().Add(
278 rtt_stats_->mean_deviation().Multiply(4)); 276 rtt_stats_->mean_deviation().Multiply(4));
279 } 277 }
280 278
281 QuicByteCount TcpCubicSender::GetCongestionWindow() const { 279 QuicByteCount TcpCubicSender::GetCongestionWindow() const {
282 return congestion_window_ * kMaxSegmentSize; 280 return congestion_window_ * kDefaultTCPMSS;
283 } 281 }
284 282
285 bool TcpCubicSender::InSlowStart() const { 283 bool TcpCubicSender::InSlowStart() const {
286 return congestion_window_ < slowstart_threshold_; 284 return congestion_window_ < slowstart_threshold_;
287 } 285 }
288 286
289 QuicByteCount TcpCubicSender::GetSlowStartThreshold() const { 287 QuicByteCount TcpCubicSender::GetSlowStartThreshold() const {
290 return slowstart_threshold_ * kMaxSegmentSize; 288 return slowstart_threshold_ * kDefaultTCPMSS;
291 } 289 }
292 290
293 bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const { 291 bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
294 const QuicByteCount congestion_window_bytes = GetCongestionWindow(); 292 const QuicByteCount congestion_window_bytes = GetCongestionWindow();
295 if (bytes_in_flight >= congestion_window_bytes) { 293 if (bytes_in_flight >= congestion_window_bytes) {
296 return true; 294 return true;
297 } 295 }
298 const QuicByteCount available_bytes = 296 const QuicByteCount available_bytes =
299 congestion_window_bytes - bytes_in_flight; 297 congestion_window_bytes - bytes_in_flight;
300 const bool slow_start_limited = InSlowStart() && 298 const bool slow_start_limited = InSlowStart() &&
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 hybrid_slow_start_.Restart(); 361 hybrid_slow_start_.Restart();
364 slowstart_threshold_ = congestion_window_ / 2; 362 slowstart_threshold_ = congestion_window_ / 2;
365 congestion_window_ = min_congestion_window_; 363 congestion_window_ = min_congestion_window_;
366 } 364 }
367 365
368 CongestionControlType TcpCubicSender::GetCongestionControlType() const { 366 CongestionControlType TcpCubicSender::GetCongestionControlType() const {
369 return reno_ ? kReno : kCubic; 367 return reno_ ? kReno : kCubic;
370 } 368 }
371 369
372 } // namespace net 370 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/tcp_cubic_sender.h ('k') | net/quic/congestion_control/tcp_cubic_sender_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698