New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discuss Application-Limited Sending #1637
Changes from 2 commits
ceab0e2
a38f3f9
b6546ab
f49e4a4
10f9ded
fb13365
3fb5df1
6f6e34c
f9aaa91
bb96c70
c21ced5
07ef710
06cf5b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -966,7 +966,6 @@ congestion window is less than ssthresh, which typically only occurs after an | |
RTO. While in slow start, QUIC increases the congestion window by the number of | ||
bytes acknowledged when each ack is processed. | ||
|
||
|
||
## Congestion Avoidance | ||
|
||
Slow start exits to congestion avoidance. Congestion avoidance in NewReno | ||
|
@@ -989,6 +988,11 @@ The recovery period limits congestion window reduction to once per round trip. | |
During recovery, the congestion window remains unchanged irrespective of new | ||
losses or increases in the ECN-CE counter. | ||
|
||
## Application Limited Sending | ||
|
||
If the sender is sufficiently application limited that the congestion window is | ||
not fully utilized, the congestion window should not be increased in slow start | ||
or congestion avoidance. | ||
|
||
## Tail Loss Probe | ||
|
||
|
@@ -1115,13 +1119,19 @@ acked_packet from sent_packets. | |
~~~ | ||
InRecovery(packet_number): | ||
return packet_number <= end_of_recovery | ||
|
||
ianswett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
IsAppLimited(): | ||
bytes_in_flight >= congestion_window - kMaximumDatagramSize | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this backward? Bytes in flight can't be greater than the congestion window, but if the bytes in flight are within one datagram of the window, you're clearly not limited. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It reads backwards to me as well. And is it the right test? @nibanks' comments suggest that there might be other ways to detect the condition of not being limited. For instance, as long as data is enqueued for sending, it might be reasonable to say that the application is waiting on the congestion controller (or pacer) to allow sending. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree this is backward. The Instead of using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems better, yes. When you say "close enough", I assume that you mean "so close that you couldn't send anything meaningful", something like headerlen+sizeof(cid)+16+sizeof(STREAM frame overhead), so maybe sizeof(cid)+32 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm okay with what's in the pseudocode -- so close you couldn't send another full-size datagram. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was specifically not defining "close enough". I am fine with a single datagram size or something smaller. |
||
|
||
OnPacketAckedCC(acked_packet): | ||
// Remove from bytes_in_flight. | ||
bytes_in_flight -= acked_packet.bytes | ||
if (InRecovery(acked_packet.packet_number)): | ||
// Do not increase congestion window in recovery period. | ||
return | ||
if (IsAppLimited()) | ||
// Do not increase congestion_window if application limited. | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This gets into implementation specifics a bit, but I don't think the pseudocode can be as trivial as this. Naively, if this function is called for two different packets in a row, without a corresponding send operation being performed between them, then only the first In a slightly more intelligent interpretation of this, where you actually preform this logic for all the bytes acknowledged in a whole ACK frame in a single call, you can still have the same problem if you end up processing two ACK frames back to back before you end up doing a send. I have some ideas on how to solve that (at least for my implementation) but I was wondering if this should be mentioned (if not pseudocoded) here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, getting this right is complex. I am going to not define the IsAppLimited() method, but document what it's intent is. |
||
if (congestion_window < ssthresh): | ||
// Slow start. | ||
congestion_window += acked_packet.bytes | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't really get a definition of "application limited" from this. The point is that you won't increase the congestion window if the entire congestion window isn't being actively used.
Is there precedent for this sort of capping of the window?
I assume that this includes flow control as the source of the limitation. Which might be worth mentioning.