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

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

Issue 605163004: Land Recent QUIC Changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Final_0925
Patch Set: Created 6 years, 2 months 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 | « net/quic/congestion_control/cubic.h ('k') | net/quic/congestion_control/pacing_sender.h » ('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) 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/cubic.h" 5 #include "net/quic/congestion_control/cubic.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 10 matching lines...) Expand all
21 // Constants based on TCP defaults. 21 // Constants based on TCP defaults.
22 // The following constants are in 2^10 fractions of a second instead of ms to 22 // The following constants are in 2^10 fractions of a second instead of ms to
23 // allow a 10 shift right to divide. 23 // allow a 10 shift right to divide.
24 const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3) 24 const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3)
25 // where 0.100 is 100 ms which is the scaling 25 // where 0.100 is 100 ms which is the scaling
26 // round trip time. 26 // round trip time.
27 const int kCubeCongestionWindowScale = 410; 27 const int kCubeCongestionWindowScale = 410;
28 const uint64 kCubeFactor = (GG_UINT64_C(1) << kCubeScale) / 28 const uint64 kCubeFactor = (GG_UINT64_C(1) << kCubeScale) /
29 kCubeCongestionWindowScale; 29 kCubeCongestionWindowScale;
30 30
31 const uint32 kNumConnections = 2; 31 const uint32 kDefaultNumConnections = 2;
32 const float kBeta = 0.7f; // Default Cubic backoff factor. 32 const float kBeta = 0.7f; // Default Cubic backoff factor.
33 // Additional backoff factor when loss occurs in the concave part of the Cubic 33 // Additional backoff factor when loss occurs in the concave part of the Cubic
34 // curve. This additional backoff factor is expected to give up bandwidth to 34 // curve. This additional backoff factor is expected to give up bandwidth to
35 // new concurrent flows and speed up convergence. 35 // new concurrent flows and speed up convergence.
36 const float kBetaLastMax = 0.85f; 36 const float kBetaLastMax = 0.85f;
37 37
38 // kNConnectionBeta is the backoff factor after loss for our N-connection
39 // emulation, which emulates the effective backoff of an ensemble of N TCP-Reno
40 // connections on a single loss event. The effective multiplier is computed as:
41 const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
42
43 // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
44 // kBeta here is a cwnd multiplier, and is equal to 1-beta from the CUBIC paper.
45 // We derive the equivalent kNConnectionAlpha for an N-connection emulation as:
46 const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
47 (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
48 // TODO(jri): Compute kNConnectionBeta and kNConnectionAlpha from
49 // number of active streams.
50
51 } // namespace 38 } // namespace
52 39
53 Cubic::Cubic(const QuicClock* clock, QuicConnectionStats* stats) 40 Cubic::Cubic(const QuicClock* clock, QuicConnectionStats* stats)
54 : clock_(clock), 41 : clock_(clock),
42 num_connections_(kDefaultNumConnections),
55 epoch_(QuicTime::Zero()), 43 epoch_(QuicTime::Zero()),
56 last_update_time_(QuicTime::Zero()), 44 last_update_time_(QuicTime::Zero()),
57 stats_(stats) { 45 stats_(stats) {
58 Reset(); 46 Reset();
59 } 47 }
60 48
49 void Cubic::SetNumConnections(int num_connections) {
50 num_connections_ = num_connections;
51 }
52
53 float Cubic::Alpha() const {
54 // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
55 // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
56 // We derive the equivalent alpha for an N-connection emulation as:
57 const float beta = Beta();
58 return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
59 }
60
61 float Cubic::Beta() const {
62 // kNConnectionBeta is the backoff factor after loss for our N-connection
63 // emulation, which emulates the effective backoff of an ensemble of N
64 // TCP-Reno connections on a single loss event. The effective multiplier is
65 // computed as:
66 return (num_connections_ - 1 + kBeta) / num_connections_;
67 }
68
61 void Cubic::Reset() { 69 void Cubic::Reset() {
62 epoch_ = QuicTime::Zero(); // Reset time. 70 epoch_ = QuicTime::Zero(); // Reset time.
63 last_update_time_ = QuicTime::Zero(); // Reset time. 71 last_update_time_ = QuicTime::Zero(); // Reset time.
64 last_congestion_window_ = 0; 72 last_congestion_window_ = 0;
65 last_max_congestion_window_ = 0; 73 last_max_congestion_window_ = 0;
66 acked_packets_count_ = 0; 74 acked_packets_count_ = 0;
67 estimated_tcp_congestion_window_ = 0; 75 estimated_tcp_congestion_window_ = 0;
68 origin_point_congestion_window_ = 0; 76 origin_point_congestion_window_ = 0;
69 time_to_origin_point_ = 0; 77 time_to_origin_point_ = 0;
70 last_target_congestion_window_ = 0; 78 last_target_congestion_window_ = 0;
(...skipping 21 matching lines...) Expand all
92 QuicTcpCongestionWindow current_congestion_window) { 100 QuicTcpCongestionWindow current_congestion_window) {
93 if (current_congestion_window < last_max_congestion_window_) { 101 if (current_congestion_window < last_max_congestion_window_) {
94 // We never reached the old max, so assume we are competing with another 102 // We never reached the old max, so assume we are competing with another
95 // flow. Use our extra back off factor to allow the other flow to go up. 103 // flow. Use our extra back off factor to allow the other flow to go up.
96 last_max_congestion_window_ = 104 last_max_congestion_window_ =
97 static_cast<int>(kBetaLastMax * current_congestion_window); 105 static_cast<int>(kBetaLastMax * current_congestion_window);
98 } else { 106 } else {
99 last_max_congestion_window_ = current_congestion_window; 107 last_max_congestion_window_ = current_congestion_window;
100 } 108 }
101 epoch_ = QuicTime::Zero(); // Reset time. 109 epoch_ = QuicTime::Zero(); // Reset time.
102 return static_cast<int>(current_congestion_window * kNConnectionBeta); 110 return static_cast<int>(current_congestion_window * Beta());
103 } 111 }
104 112
105 QuicTcpCongestionWindow Cubic::CongestionWindowAfterAck( 113 QuicTcpCongestionWindow Cubic::CongestionWindowAfterAck(
106 QuicTcpCongestionWindow current_congestion_window, 114 QuicTcpCongestionWindow current_congestion_window,
107 QuicTime::Delta delay_min) { 115 QuicTime::Delta delay_min) {
108 acked_packets_count_ += 1; // Packets acked. 116 acked_packets_count_ += 1; // Packets acked.
109 QuicTime current_time = clock_->ApproximateNow(); 117 QuicTime current_time = clock_->ApproximateNow();
110 118
111 // Cubic is "independent" of RTT, the update is limited by the time elapsed. 119 // Cubic is "independent" of RTT, the update is limited by the time elapsed.
112 if (last_congestion_window_ == current_congestion_window && 120 if (last_congestion_window_ == current_congestion_window &&
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 QuicTcpCongestionWindow target_congestion_window = 156 QuicTcpCongestionWindow target_congestion_window =
149 origin_point_congestion_window_ - delta_congestion_window; 157 origin_point_congestion_window_ - delta_congestion_window;
150 158
151 DCHECK_LT(0u, estimated_tcp_congestion_window_); 159 DCHECK_LT(0u, estimated_tcp_congestion_window_);
152 // With dynamic beta/alpha based on number of active streams, it is possible 160 // With dynamic beta/alpha based on number of active streams, it is possible
153 // for the required_ack_count to become much lower than acked_packets_count_ 161 // for the required_ack_count to become much lower than acked_packets_count_
154 // suddenly, leading to more than one iteration through the following loop. 162 // suddenly, leading to more than one iteration through the following loop.
155 while (true) { 163 while (true) {
156 // Update estimated TCP congestion_window. 164 // Update estimated TCP congestion_window.
157 uint32 required_ack_count = 165 uint32 required_ack_count =
158 estimated_tcp_congestion_window_ / kNConnectionAlpha; 166 estimated_tcp_congestion_window_ / Alpha();
159 if (acked_packets_count_ < required_ack_count) { 167 if (acked_packets_count_ < required_ack_count) {
160 break; 168 break;
161 } 169 }
162 acked_packets_count_ -= required_ack_count; 170 acked_packets_count_ -= required_ack_count;
163 estimated_tcp_congestion_window_++; 171 estimated_tcp_congestion_window_++;
164 } 172 }
165 173
166 // Update cubic mode and reno mode stats in QuicConnectionStats. 174 // Update cubic mode and reno mode stats in QuicConnectionStats.
167 UpdateCongestionControlStats(target_congestion_window, 175 UpdateCongestionControlStats(target_congestion_window,
168 estimated_tcp_congestion_window_); 176 estimated_tcp_congestion_window_);
169 177
170 // We have a new cubic congestion window. 178 // We have a new cubic congestion window.
171 last_target_congestion_window_ = target_congestion_window; 179 last_target_congestion_window_ = target_congestion_window;
172 180
173 // Compute target congestion_window based on cubic target and estimated TCP 181 // Compute target congestion_window based on cubic target and estimated TCP
174 // congestion_window, use highest (fastest). 182 // congestion_window, use highest (fastest).
175 if (target_congestion_window < estimated_tcp_congestion_window_) { 183 if (target_congestion_window < estimated_tcp_congestion_window_) {
176 target_congestion_window = estimated_tcp_congestion_window_; 184 target_congestion_window = estimated_tcp_congestion_window_;
177 } 185 }
178 186
179 DVLOG(1) << "Target congestion_window: " << target_congestion_window; 187 DVLOG(1) << "Target congestion_window: " << target_congestion_window;
180 return target_congestion_window; 188 return target_congestion_window;
181 } 189 }
182 190
183 } // namespace net 191 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/cubic.h ('k') | net/quic/congestion_control/pacing_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698