OLD | NEW |
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 last_update_time_ = QuicTime::Zero(); // Reset time. | 71 last_update_time_ = QuicTime::Zero(); // Reset time. |
72 last_congestion_window_ = 0; | 72 last_congestion_window_ = 0; |
73 last_max_congestion_window_ = 0; | 73 last_max_congestion_window_ = 0; |
74 acked_packets_count_ = 0; | 74 acked_packets_count_ = 0; |
75 estimated_tcp_congestion_window_ = 0; | 75 estimated_tcp_congestion_window_ = 0; |
76 origin_point_congestion_window_ = 0; | 76 origin_point_congestion_window_ = 0; |
77 time_to_origin_point_ = 0; | 77 time_to_origin_point_ = 0; |
78 last_target_congestion_window_ = 0; | 78 last_target_congestion_window_ = 0; |
79 } | 79 } |
80 | 80 |
81 void Cubic::UpdateCongestionControlStats( | 81 void Cubic::UpdateCongestionControlStats(QuicPacketCount new_cubic_mode_cwnd, |
82 QuicTcpCongestionWindow new_cubic_mode_cwnd, | 82 QuicPacketCount new_reno_mode_cwnd) { |
83 QuicTcpCongestionWindow new_reno_mode_cwnd) { | |
84 | 83 |
85 QuicTcpCongestionWindow highest_new_cwnd = max(new_cubic_mode_cwnd, | 84 QuicPacketCount highest_new_cwnd = max(new_cubic_mode_cwnd, |
86 new_reno_mode_cwnd); | 85 new_reno_mode_cwnd); |
87 if (last_congestion_window_ < highest_new_cwnd) { | 86 if (last_congestion_window_ < highest_new_cwnd) { |
88 // cwnd will increase to highest_new_cwnd. | 87 // cwnd will increase to highest_new_cwnd. |
89 stats_->cwnd_increase_congestion_avoidance += | 88 stats_->cwnd_increase_congestion_avoidance += |
90 highest_new_cwnd - last_congestion_window_; | 89 highest_new_cwnd - last_congestion_window_; |
91 if (new_cubic_mode_cwnd > new_reno_mode_cwnd) { | 90 if (new_cubic_mode_cwnd > new_reno_mode_cwnd) { |
92 // This cwnd increase is due to cubic mode. | 91 // This cwnd increase is due to cubic mode. |
93 stats_->cwnd_increase_cubic_mode += | 92 stats_->cwnd_increase_cubic_mode += |
94 new_cubic_mode_cwnd - last_congestion_window_; | 93 new_cubic_mode_cwnd - last_congestion_window_; |
95 } | 94 } |
96 } | 95 } |
97 } | 96 } |
98 | 97 |
99 QuicTcpCongestionWindow Cubic::CongestionWindowAfterPacketLoss( | 98 QuicPacketCount Cubic::CongestionWindowAfterPacketLoss( |
100 QuicTcpCongestionWindow current_congestion_window) { | 99 QuicPacketCount current_congestion_window) { |
101 if (current_congestion_window < last_max_congestion_window_) { | 100 if (current_congestion_window < last_max_congestion_window_) { |
102 // We never reached the old max, so assume we are competing with another | 101 // We never reached the old max, so assume we are competing with another |
103 // flow. Use our extra back off factor to allow the other flow to go up. | 102 // flow. Use our extra back off factor to allow the other flow to go up. |
104 last_max_congestion_window_ = | 103 last_max_congestion_window_ = |
105 static_cast<int>(kBetaLastMax * current_congestion_window); | 104 static_cast<int>(kBetaLastMax * current_congestion_window); |
106 } else { | 105 } else { |
107 last_max_congestion_window_ = current_congestion_window; | 106 last_max_congestion_window_ = current_congestion_window; |
108 } | 107 } |
109 epoch_ = QuicTime::Zero(); // Reset time. | 108 epoch_ = QuicTime::Zero(); // Reset time. |
110 return static_cast<int>(current_congestion_window * Beta()); | 109 return static_cast<int>(current_congestion_window * Beta()); |
111 } | 110 } |
112 | 111 |
113 QuicTcpCongestionWindow Cubic::CongestionWindowAfterAck( | 112 QuicPacketCount Cubic::CongestionWindowAfterAck( |
114 QuicTcpCongestionWindow current_congestion_window, | 113 QuicPacketCount current_congestion_window, |
115 QuicTime::Delta delay_min) { | 114 QuicTime::Delta delay_min) { |
116 acked_packets_count_ += 1; // Packets acked. | 115 acked_packets_count_ += 1; // Packets acked. |
117 QuicTime current_time = clock_->ApproximateNow(); | 116 QuicTime current_time = clock_->ApproximateNow(); |
118 | 117 |
119 // Cubic is "independent" of RTT, the update is limited by the time elapsed. | 118 // Cubic is "independent" of RTT, the update is limited by the time elapsed. |
120 if (last_congestion_window_ == current_congestion_window && | 119 if (last_congestion_window_ == current_congestion_window && |
121 (current_time.Subtract(last_update_time_) <= MaxCubicTimeInterval())) { | 120 (current_time.Subtract(last_update_time_) <= MaxCubicTimeInterval())) { |
122 return max(last_target_congestion_window_, | 121 return max(last_target_congestion_window_, |
123 estimated_tcp_congestion_window_); | 122 estimated_tcp_congestion_window_); |
124 } | 123 } |
(...skipping 18 matching lines...) Expand all Loading... |
143 } | 142 } |
144 } | 143 } |
145 // Change the time unit from microseconds to 2^10 fractions per second. Take | 144 // Change the time unit from microseconds to 2^10 fractions per second. Take |
146 // the round trip time in account. This is done to allow us to use shift as a | 145 // the round trip time in account. This is done to allow us to use shift as a |
147 // divide operator. | 146 // divide operator. |
148 int64 elapsed_time = | 147 int64 elapsed_time = |
149 (current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) / | 148 (current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) / |
150 base::Time::kMicrosecondsPerSecond; | 149 base::Time::kMicrosecondsPerSecond; |
151 | 150 |
152 int64 offset = time_to_origin_point_ - elapsed_time; | 151 int64 offset = time_to_origin_point_ - elapsed_time; |
153 QuicTcpCongestionWindow delta_congestion_window = (kCubeCongestionWindowScale | 152 QuicPacketCount delta_congestion_window = (kCubeCongestionWindowScale |
154 * offset * offset * offset) >> kCubeScale; | 153 * offset * offset * offset) >> kCubeScale; |
155 | 154 |
156 QuicTcpCongestionWindow target_congestion_window = | 155 QuicPacketCount target_congestion_window = |
157 origin_point_congestion_window_ - delta_congestion_window; | 156 origin_point_congestion_window_ - delta_congestion_window; |
158 | 157 |
159 DCHECK_LT(0u, estimated_tcp_congestion_window_); | 158 DCHECK_LT(0u, estimated_tcp_congestion_window_); |
160 // With dynamic beta/alpha based on number of active streams, it is possible | 159 // With dynamic beta/alpha based on number of active streams, it is possible |
161 // for the required_ack_count to become much lower than acked_packets_count_ | 160 // for the required_ack_count to become much lower than acked_packets_count_ |
162 // suddenly, leading to more than one iteration through the following loop. | 161 // suddenly, leading to more than one iteration through the following loop. |
163 while (true) { | 162 while (true) { |
164 // Update estimated TCP congestion_window. | 163 // Update estimated TCP congestion_window. |
165 uint32 required_ack_count = | 164 uint32 required_ack_count = |
166 estimated_tcp_congestion_window_ / Alpha(); | 165 estimated_tcp_congestion_window_ / Alpha(); |
(...skipping 15 matching lines...) Expand all Loading... |
182 // congestion_window, use highest (fastest). | 181 // congestion_window, use highest (fastest). |
183 if (target_congestion_window < estimated_tcp_congestion_window_) { | 182 if (target_congestion_window < estimated_tcp_congestion_window_) { |
184 target_congestion_window = estimated_tcp_congestion_window_; | 183 target_congestion_window = estimated_tcp_congestion_window_; |
185 } | 184 } |
186 | 185 |
187 DVLOG(1) << "Target congestion_window: " << target_congestion_window; | 186 DVLOG(1) << "Target congestion_window: " << target_congestion_window; |
188 return target_congestion_window; | 187 return target_congestion_window; |
189 } | 188 } |
190 | 189 |
191 } // namespace net | 190 } // namespace net |
OLD | NEW |