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

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

Issue 761903003: Update from https://crrev.com/306655 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/send_algorithm_simulator.h" 5 #include "net/quic/congestion_control/send_algorithm_simulator.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "net/quic/crypto/quic_random.h" 11 #include "net/quic/crypto/quic_random.h"
12 12
13 using std::list; 13 using std::list;
14 using std::make_pair; 14 using std::make_pair;
15 using std::max; 15 using std::max;
16 using std::min; 16 using std::min;
17 using std::vector; 17 using std::vector;
18 18
19 namespace net { 19 namespace net {
20 20
21 namespace { 21 namespace {
22 22
23 const QuicByteCount kPacketSize = 1200; 23 const QuicByteCount kPacketSize = 1200;
24 24
25 } // namespace 25 } // namespace
26 26
27 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm, 27 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm,
28 RttStats* rtt_stats) 28 RttStats* rtt_stats)
29 : Sender(send_algorithm, rtt_stats, QuicTime::Delta::Zero()) {}
30
31 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm,
32 RttStats* rtt_stats,
33 QuicTime::Delta additional_rtt)
29 : send_algorithm(send_algorithm), 34 : send_algorithm(send_algorithm),
30 rtt_stats(rtt_stats), 35 rtt_stats(rtt_stats),
36 additional_rtt(additional_rtt),
31 last_sent(0), 37 last_sent(0),
32 last_acked(0), 38 last_acked(0),
33 next_acked(1), 39 next_acked(1),
34 max_cwnd(0), 40 max_cwnd(0),
35 min_cwnd(100000), 41 min_cwnd(100000),
36 max_cwnd_drop(0), 42 max_cwnd_drop(0),
37 last_cwnd(0), 43 last_cwnd(0),
38 last_transfer_bandwidth(QuicBandwidth::Zero()), 44 last_transfer_bandwidth(QuicBandwidth::Zero()),
39 last_transfer_loss_rate(0) {} 45 last_transfer_loss_rate(0) {}
40 46
47 SendAlgorithmSimulator::Transfer::Transfer(Sender* sender,
48 QuicByteCount num_bytes,
49 QuicTime start_time,
50 string name)
51 : sender(sender),
52 num_bytes(num_bytes),
53 bytes_acked(0),
54 bytes_lost(0),
55 bytes_in_flight(0),
56 start_time(start_time),
57 name(name) {}
58
41 SendAlgorithmSimulator::SendAlgorithmSimulator( 59 SendAlgorithmSimulator::SendAlgorithmSimulator(
42 MockClock* clock, 60 MockClock* clock,
43 QuicBandwidth bandwidth, 61 QuicBandwidth bandwidth,
44 QuicTime::Delta rtt) 62 QuicTime::Delta rtt)
45 : clock_(clock), 63 : clock_(clock),
46 lose_next_ack_(false), 64 lose_next_ack_(false),
47 forward_loss_rate_(0), 65 forward_loss_rate_(0),
48 reverse_loss_rate_(0), 66 reverse_loss_rate_(0),
49 loss_correlation_(0), 67 loss_correlation_(0),
50 bandwidth_(bandwidth), 68 bandwidth_(bandwidth),
51 rtt_(rtt), 69 rtt_(rtt),
52 buffer_size_(1000000), 70 buffer_size_(1000000),
53 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) { 71 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
54 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); 72 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
55 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; 73 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
56 simple_random_.set_seed(seed); 74 simple_random_.set_seed(seed);
57 } 75 }
58 76
59 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} 77 SendAlgorithmSimulator::~SendAlgorithmSimulator() {}
60 78
61 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) { 79 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
62 AddTransfer(sender, num_bytes, clock_->Now()); 80 AddTransfer(sender, num_bytes, clock_->Now(),
81 StringPrintf("#%zu", pending_transfers_.size()));
63 } 82 }
64 83
65 void SendAlgorithmSimulator::AddTransfer( 84 void SendAlgorithmSimulator::AddTransfer(
66 Sender* sender, size_t num_bytes, QuicTime start_time) { 85 Sender* sender, size_t num_bytes, QuicTime start_time, string name) {
67 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time)); 86 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time, name));
68 // Record initial stats from when the transfer begins. 87 // Record initial stats from when the transfer begins.
69 pending_transfers_.back().sender->RecordStats(); 88 pending_transfers_.back().sender->RecordStats();
70 } 89 }
71 90
72 void SendAlgorithmSimulator::TransferBytes() { 91 void SendAlgorithmSimulator::TransferBytes() {
73 TransferBytes(kuint64max, QuicTime::Delta::Infinite()); 92 TransferBytes(kuint64max, QuicTime::Delta::Infinite());
74 } 93 }
75 94
76 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, 95 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
77 QuicTime::Delta max_time) { 96 QuicTime::Delta max_time) {
(...skipping 17 matching lines...) Expand all
95 SendDataNow(&pending_transfers_.front()); 114 SendDataNow(&pending_transfers_.front());
96 } else if (ack_event.time_delta < send_event.time_delta) { 115 } else if (ack_event.time_delta < send_event.time_delta) {
97 DVLOG(1) << "Handling ack of largest observed:" 116 DVLOG(1) << "Handling ack of largest observed:"
98 << ack_event.transfer->sender->next_acked << ", advancing time:" 117 << ack_event.transfer->sender->next_acked << ", advancing time:"
99 << ack_event.time_delta.ToMicroseconds() << "us"; 118 << ack_event.time_delta.ToMicroseconds() << "us";
100 // Ack data all the data up to ack time and lose any missing sequence 119 // Ack data all the data up to ack time and lose any missing sequence
101 // numbers. 120 // numbers.
102 clock_->AdvanceTime(ack_event.time_delta); 121 clock_->AdvanceTime(ack_event.time_delta);
103 HandlePendingAck(ack_event.transfer); 122 HandlePendingAck(ack_event.transfer);
104 } else { 123 } else {
105 DVLOG(1) << "Sending, advancing time:" 124 DVLOG(1) << "Sending transfer '" << send_event.transfer->name
106 << send_event.time_delta.ToMicroseconds() << "us"; 125 << "', advancing time:" << send_event.time_delta.ToMicroseconds()
126 << "us";
107 clock_->AdvanceTime(send_event.time_delta); 127 clock_->AdvanceTime(send_event.time_delta);
108 SendDataNow(send_event.transfer); 128 SendDataNow(send_event.transfer);
109 bytes_sent += kPacketSize; 129 bytes_sent += kPacketSize;
110 } 130 }
111 } 131 }
112 } 132 }
113 133
114 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { 134 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
115 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite(); 135 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite();
116 Transfer* transfer = nullptr; 136 Transfer* transfer = nullptr;
117 for (vector<Transfer>::iterator it = pending_transfers_.begin(); 137 for (vector<Transfer>::iterator it = pending_transfers_.begin();
118 it != pending_transfers_.end(); ++it) { 138 it != pending_transfers_.end(); ++it) {
119 // If we've already sent enough bytes, wait for them to be acked. 139 // If we've already sent enough bytes, wait for them to be acked.
120 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { 140 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) {
121 continue; 141 continue;
122 } 142 }
123 // If the flow hasn't started, use the start time. 143 // If the flow hasn't started, use the start time.
124 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now()); 144 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now());
125 if (clock_->Now() >= it->start_time) { 145 if (clock_->Now() >= it->start_time) {
126 transfer_send_time = 146 transfer_send_time =
127 it->sender->send_algorithm->TimeUntilSend( 147 it->sender->send_algorithm->TimeUntilSend(
128 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); 148 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
129 } 149 }
130 if (transfer_send_time < next_send_time) { 150 if (transfer_send_time < next_send_time) {
131 next_send_time = transfer_send_time; 151 next_send_time = transfer_send_time;
132 transfer = &(*it); 152 transfer = &(*it);
133 } 153 }
134 } 154 }
135 DVLOG(1) << "NextSendTime returning delta(ms):" 155 DVLOG(1) << "NextSendTime returning delta(ms):"
136 << next_send_time.ToMilliseconds(); 156 << next_send_time.ToMilliseconds() << ", transfer '"
157 << transfer->name;
137 return PacketEvent(next_send_time, transfer); 158 return PacketEvent(next_send_time, transfer);
138 } 159 }
139 160
140 // NextAck takes into account packet loss in both forward and reverse 161 // NextAck takes into account packet loss in both forward and reverse
141 // direction, as well as correlated losses. And it assumes the receiver acks 162 // direction, as well as correlated losses. And it assumes the receiver acks
142 // every other packet when there is no loss. 163 // every other packet when there is no loss.
143 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { 164 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() {
144 if (sent_packets_.empty()) { 165 if (sent_packets_.empty()) {
145 DVLOG(1) << "No outstanding packets to ack for any transfer."; 166 DVLOG(1) << "No outstanding packets to ack for any transfer.";
146 return PacketEvent(QuicTime::Delta::Infinite(), nullptr); 167 return PacketEvent(QuicTime::Delta::Infinite(), nullptr);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 } 227 }
207 *next_acked = it->sequence_number; 228 *next_acked = it->sequence_number;
208 ack_delay = it->ack_time.Subtract(clock_->Now()); 229 ack_delay = it->ack_time.Subtract(clock_->Now());
209 if (HasRecentLostPackets(transfer, *next_acked) || 230 if (HasRecentLostPackets(transfer, *next_acked) ||
210 (*next_acked - last_acked) >= 2) { 231 (*next_acked - last_acked) >= 2) {
211 break; 232 break;
212 } 233 }
213 ack_delay = ack_delay.Add(delayed_ack_timer_); 234 ack_delay = ack_delay.Add(delayed_ack_timer_);
214 } 235 }
215 236
216 DVLOG(1) << "FindNextAcked found next_acked_:" 237 DVLOG(1) << "FindNextAck found next_acked_:" << transfer->sender->next_acked
217 << transfer->sender->next_acked
218 << " last_acked:" << transfer->sender->last_acked 238 << " last_acked:" << transfer->sender->last_acked
219 << " ack_delay(ms):" << ack_delay.ToMilliseconds(); 239 << " ack_time(ms):" << ack_delay.ToMilliseconds();
220 return ack_delay; 240 return ack_delay;
221 } 241 }
222 242
223 bool SendAlgorithmSimulator::HasRecentLostPackets( 243 bool SendAlgorithmSimulator::HasRecentLostPackets(
224 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const { 244 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const {
225 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked; 245 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked;
226 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 246 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
227 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) { 247 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) {
228 if (transfer != it->transfer) { 248 if (transfer != it->transfer) {
229 continue; 249 continue;
(...skipping 11 matching lines...) Expand all
241 } 261 }
242 return false; 262 return false;
243 } 263 }
244 264
245 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { 265 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
246 Sender* sender = transfer->sender; 266 Sender* sender = transfer->sender;
247 DCHECK_LT(sender->last_acked, sender->next_acked); 267 DCHECK_LT(sender->last_acked, sender->next_acked);
248 SendAlgorithmInterface::CongestionVector acked_packets; 268 SendAlgorithmInterface::CongestionVector acked_packets;
249 SendAlgorithmInterface::CongestionVector lost_packets; 269 SendAlgorithmInterface::CongestionVector lost_packets;
250 DVLOG(1) << "Acking packets from:" << sender->last_acked 270 DVLOG(1) << "Acking packets from:" << sender->last_acked
251 << " to " << sender->next_acked 271 << " to " << sender->next_acked
252 << " bytes_in_flight:" << transfer->bytes_in_flight 272 << " bytes_in_flight:" << transfer->bytes_in_flight
253 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; 273 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
254 // Some entries may be missing from the sent_packets_ array, if they were 274 // Some entries may be missing from the sent_packets_ array, if they were
255 // dropped due to buffer overruns. 275 // dropped due to buffer overruns.
256 SentPacket largest_observed; 276 SentPacket largest_observed;
257 list<SentPacket>::iterator it = sent_packets_.begin(); 277 list<SentPacket>::iterator it = sent_packets_.begin();
258 while (sender->last_acked < sender->next_acked) { 278 while (sender->last_acked < sender->next_acked) {
259 ++sender->last_acked; 279 ++sender->last_acked;
260 TransmissionInfo info = TransmissionInfo(); 280 TransmissionInfo info = TransmissionInfo();
261 info.bytes_sent = kPacketSize; 281 info.bytes_sent = kPacketSize;
262 info.in_flight = true; 282 info.in_flight = true;
263 // Find the next SentPacket for this transfer. 283 // Find the next SentPacket for this transfer.
(...skipping 11 matching lines...) Expand all
275 if (it->lost) { 295 if (it->lost) {
276 lost_packets.push_back(make_pair(sender->last_acked, info)); 296 lost_packets.push_back(make_pair(sender->last_acked, info));
277 } else { 297 } else {
278 acked_packets.push_back(make_pair(sender->last_acked, info)); 298 acked_packets.push_back(make_pair(sender->last_acked, info));
279 } 299 }
280 // This packet has been acked or lost, remove it from sent_packets_. 300 // This packet has been acked or lost, remove it from sent_packets_.
281 largest_observed = *it; 301 largest_observed = *it;
282 sent_packets_.erase(it++); 302 sent_packets_.erase(it++);
283 } 303 }
284 304
285 DCHECK(largest_observed.ack_time.IsInitialized()); 305 DCHECK(!largest_observed.lost);
286 DVLOG(1) << "Updating RTT from send_time:" 306 DVLOG(1) << "Updating RTT from send_time:"
287 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" 307 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
288 << largest_observed.ack_time.ToDebuggingValue(); 308 << largest_observed.ack_time.ToDebuggingValue();
289 QuicTime::Delta measured_rtt = 309 QuicTime::Delta measured_rtt =
290 largest_observed.ack_time.Subtract(largest_observed.send_time); 310 largest_observed.ack_time.Subtract(largest_observed.send_time);
291 DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds()); 311 DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
292 sender->rtt_stats->UpdateRtt(measured_rtt, 312 sender->rtt_stats->UpdateRtt(measured_rtt,
293 QuicTime::Delta::Zero(), 313 QuicTime::Delta::Zero(),
294 clock_->Now()); 314 clock_->Now());
295 sender->send_algorithm->OnCongestionEvent( 315 sender->send_algorithm->OnCongestionEvent(
(...skipping 24 matching lines...) Expand all
320 break; 340 break;
321 } 341 }
322 } 342 }
323 } 343 }
324 } 344 }
325 345
326 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { 346 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
327 Sender* sender = transfer->sender; 347 Sender* sender = transfer->sender;
328 ++sender->last_sent; 348 ++sender->last_sent;
329 DVLOG(1) << "Sending packet:" << sender->last_sent 349 DVLOG(1) << "Sending packet:" << sender->last_sent
350 << " name:" << transfer->name
330 << " bytes_in_flight:" << transfer->bytes_in_flight 351 << " bytes_in_flight:" << transfer->bytes_in_flight
352 << " cwnd:" << sender->send_algorithm->GetCongestionWindow()
331 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; 353 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
332 sender->send_algorithm->OnPacketSent( 354 sender->send_algorithm->OnPacketSent(
333 clock_->Now(), transfer->bytes_in_flight, 355 clock_->Now(), transfer->bytes_in_flight,
334 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); 356 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
335 // Lose the packet immediately if the buffer is full. 357 // Lose the packet immediately if the buffer is full.
336 if (sent_packets_.size() * kPacketSize < buffer_size_) { 358 if (sent_packets_.size() * kPacketSize < buffer_size_) {
337 // TODO(ianswett): This buffer simulation is an approximation. 359 // TODO(ianswett): This buffer simulation is an approximation.
338 // An ack time of zero means loss. 360 // An ack time of zero means loss.
339 bool packet_lost = 361 bool packet_lost =
340 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); 362 forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
341 // Handle correlated loss. 363 // Handle correlated loss.
342 if (!sent_packets_.empty() && sent_packets_.back().lost && 364 if (!sent_packets_.empty() && sent_packets_.back().lost &&
343 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { 365 loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
344 packet_lost = true; 366 packet_lost = true;
345 } 367 }
346 DVLOG(1) << "losing packet:" << sender->last_sent 368 DVLOG(1) << "losing packet:" << sender->last_sent
347 << " due to random loss."; 369 << " name:" << transfer->name << " due to random loss.";
348 370
349 // If the number of bytes in flight are less than the bdp, there's 371 // If the number of bytes in flight are less than the bdp, there's
350 // no buffering delay. Bytes lost from the buffer are not counted. 372 // no buffering delay. Bytes lost from the buffer are not counted.
351 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); 373 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
352 QuicTime ack_time = clock_->Now().Add(rtt_); 374 QuicTime ack_time = clock_->Now().Add(rtt_).Add(sender->additional_rtt);
353 if (kPacketSize > bdp) { 375 if (kPacketSize > bdp) {
354 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp)); 376 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
355 } 377 }
356 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() : 378 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
357 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize)); 379 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
358 ack_time = QuicTime::Max(ack_time, queue_ack_time); 380 ack_time = QuicTime::Max(ack_time, queue_ack_time);
359 sent_packets_.push_back(SentPacket( 381 sent_packets_.push_back(SentPacket(
360 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer)); 382 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer));
361 } else { 383 } else {
362 DVLOG(1) << "losing packet:" << sender->last_sent 384 DVLOG(1) << "losing packet:" << sender->last_sent
363 << " because the buffer was full."; 385 << " name:" << transfer->name << " because the buffer was full.";
364 } 386 }
365 transfer->bytes_in_flight += kPacketSize; 387 transfer->bytes_in_flight += kPacketSize;
366 } 388 }
367 389
368 // Advance the time by |delta| without sending anything. 390 // Advance the time by |delta| without sending anything.
369 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { 391 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
370 clock_->AdvanceTime(delta); 392 clock_->AdvanceTime(delta);
371 } 393 }
372 394
373 } // namespace net 395 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/send_algorithm_simulator.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