Subject: [tcpm] thoughts on newcwv-05

From: [email-masked]
Date: Thu, 27 Feb 2014 09:08:28 -0000

Mark,

Thank you the review. It is really helpful having new eyes on something
that has been evolving over a time and those who have been reading this
and updating already understand the context. Please see our proposed plan
below, marked by ":".

Gorry, Raffaello and Arjuna.

---

Hi folks!

I took a spin through newcwv-05 yesterday.  I scribbled down some
thoughts and figured I'd share.  I am mostly a lurker and haven't really
followed the discussion of this document on the list.  So, this is
perhaps old stuff, but I prefer to think of it as I am coming with fresh
eyes.

  + This:

       Standard TCP [RFC5681] requires the cwnd to be reset to the
       restart window (RW) when an application becomes idle.

    is just wrong.  RFC 5681 says

       Therefore, a TCP SHOULD set cwnd to no more than RW before
       beginning transmission if the TCP has not sent data in an
       interval exceeding the retransmission timeout.

    I.e., there is no requirement, just a strong recommendation.
: We Agree.
: EDIT: s/requires the cwnd to be reset/SHOULD reset/

  + I would suggest using the terminology of RFC 2681.  I.e.,
    "application limited periods" not "rate-limiting".  Unless of course
    you mean something different.  If that is the case then you should
    sketch the difference.  But, be consistent where you can.

: Actually this is more difficult that it seems, the terminology in
: RFC 2861 referred to something different, and for quite some time
: the WG have used the new terminology.
: We can and will note this in the intro.

  + By the end of sections 1 & 2 I figured I'd have some notion about
    why we are inventing a new CWV.  But, the best I can come up with is
    the old CWV is "too conservative for many common rate-limited
    applications".  And, that might be fine if that was well explained,
    but it doesn't really go further than that partial sentence.

    Why is CWV too conservative?  Why is it OK to be more aggressive?
    What sorts of applications does the old version hinder?

    RFC 2681 is a very nicely methodical treatment of why the mechanism
    is defined as it is.  It clearly highlights that it is
    conservative.  But, it roots that conservativism in the rest of
    TCP's operation and principles.  I would expect that if you were
    going to update CWV and/or make it more conservative that you would
    likewise articulate why you think it is OK to be more aggressive and
    what sorts of principles you are using to guide how much
    aggressiveness is OK.

    Unfortunately, this document offers none of that.  It reads as an
    ad-hoc bag of tricks that makes CWV more aggressive for nebulous
    reasons and with mechanisms/constants/algorithms that are simply
    pulled from thin air.  I assume pulling this spec out of thin air is
    not the approach that was used.  So, it shouldn't be a big deal to
    explain why you did what you did and why that is a reasonable
    change.

: OK, so you seem to suggest more of a preface to "why this"?
: - we shall add more.

  + Specifically, it has always seemed to me like CWV tries to stay out
    of the way.  The only time it really limits transmissions is when
    those transmissions (by the application) are sent at a higher rate
    than is currently validated by the load being placed on the network.
    So, reading the tea leaves on this document it seems that you aim to
    support applications that place a load on the network that is more
    volatile than nicely accommodated by CWV.  This is the sort of thing
    I'd expect to see systematically described in this document.  But, I
    am left to working this notion up myself.

  + Also, along the same lines the document says things like "It is
    expected that this update will satisfy the requirements of many
    rate-limited applications".  Well, OK.  But, **what are those
    requirements**?  You never tell us.  Why do you expect us to believe
    your algorithm addresses them?  There is no basis for statements
    like this.  I could say "newcwv does not satisfy the requirements of
    many rate-limited applications" and be on just as firm of ground as
    you when you make the statement you do.

: We shall add text on requirements.
: The goal of the update is to better accommodate applications that vary
: rate, either with (short) idle periods between transmission or by
: changing the rate the application sends. These applications are
: characterised by the FlightSize often being less than cwnd.
: Many modern applications display this behaviour, including
: web browsing, applications that support query/response type
: activities, file sharing (e.g. NFS), live video transmission.
: Many such applications currently avoid using long-lived (persistent)
: TCP connections, and either use a succession of short TCP transfers
: or use UDP. To enable better performance with TCP, some OS
: have chosen to support non-standard methods, or applications
: have resorted to "padding" streams.
:
: The goals of the draft could be phrased as:
: * Not to update the behaviour of TCP when performing a bulk transfer.
: * To reduce transfer latency for apps that change their rate
:   over short intervals of time.
: * To avoid a TCP sender growing a large "unvalidated" cwnd
:   when it has not recently sent using the cwnd.
: * To remove the incentive for ad-hoc application or network stack
:   methods (such as "padding") solely to maintain
:   a large cwmd in case of future transmission.
: * To incentivise the use of long-lived connections, rather than
:   a succession of short-lived flows, benefiting both flows and
:   network when actual congestion is encountered.
: * To provide a method that co-exists with Standard TCP and other
:   flows that use the updated method.
:
: - we plan to add some text on this to the draft.

  + Given the above it is difficult to really inhale the rest of the
    document (the algorithm) because I am not sure what you're really
    trying to accomplish.  So, the rest of these comments could well be
    half-baked.

  + "[newcwv] also reduces the incentive for an application to send data
    simply to keep transport congestion state.  (This is sometimes known
    as "padding")."

    Fair enough.  But, wouldn't it also be fair to sketch the other side
    of the coin?  I.e., that by treating state as "valid" for longer
    periods of time you increase the chances that the "valid" state is
    actually wrong?  Seemingly a balanced treatment would call out the
    pros and the cons.

: OK we will add text on merits and demerits.

  + This:

      [RFC5681] defines a variable, FlightSize, that indicates the
      amount of outstanding data in the network.  This is assumed to be
      equal to the value of Pipe calculated based on the pipe algorithm
      [RFC3517].

    is just wrong.  FlightSize and Pipe seek to assess the same sort of
    thing.  But, they are not **equal**.  And, Pipe is only valid for
    loss recovery.  FlightSize is the amount of data sent by not
    cumulatively acknowledged.  During loss recovery that value is not
    an accurate representation of the data that is in the network.
    Therefore, we calculate a *different* variable called Pipe that
    takes into account SACK information to form a more precise notion of
    what is in the network.

: That's all true. We will correct.

  + "The method RECOMMENDS that the TCP SACK option [RFC3517]"

    This should be [RFC2018], which defines the option.

: We will change to RFC2018.

  + Also, [RFC3517] should be [RFC6675] unless there is a specific
    reason to cite the old version.

: We will change to RFC6675.

  + I find this:

      The value 1/2 was selected to reduce the effects of variations in
      the pipeACK variable, and to allow the sender some flexibility in
      when it sends data.

    To be isomorphic of "The value of 1/2 was selected out of the thin
    blue air."

    I.e., wouldn't a sentence with a different value like this:

      The value 5/8 was selected to reduce the effects of variations in
      the pipeACK variable, and to allow the sender some flexibility in
      when it sends data.

    Be just as valid?

    You are just pretending to justify the magic number you have chosen
    when in fact you are saying nothing at all.

  + Now, I could better justify the choice of 1/2 based on TCP's
    operation.  I think perhaps you could note that:

    (1) When TCP is not filling the network during slow start we find it
        acceptable to double the load from one RTT to the next.
        Therefore, as long as we treat the validated phase as being at
        least 1/2*cwnd we will not cause more than a doubling from one
        RTT to the next and hence this is consistent with TCP's
        principles.

    (2) On the other hand, when we store more than 1/2*cwnd worth of
        permission to send then we can increase the rate (from one RTT
        to the next) faster than TCP would naturally and therefore in
        this regime we need to be more careful and adjust the cwnd.

    That roots your choice in something more fundamental than thin air
    and at least attempts to justify things.

: This (1,2) seems like the rationale that was presented to TCPM.
: I propose we incroporate this text.

    One might argue that the constant really should be 2/3 because with
    delayed ACKs---which are commonplace---the increase between two RTTs
    is at most 50%.  We could discuss this, I suppose.  On the one hand,
    that is probably closer to operationally correct.  On the other
    hand, I wrote the ABC spec.

: You could argue that, I'm not sure that 2/3 results in much change
: Earlier versions of the draft used this. One consistent value is
: better.

  + "A TCP sender that enters the non-validated phase will preserve the
    cwnd"

    I don't like "will".  I think you mean "MUST" or perhaps "SHOULD".
    Something prescriptive anyway.

: I'm OK to change the text, but I saw this is a statement of fact,
: since the terminology below defines this mechanism more precisely:
:  *  A sender that is cwnd-limited MAY use the standard TCP method
:        to increase cwnd (i.e. a TCP sender that fully utilises the
:         cwnd is permitted to increase cwnd each received ACK using
:        standard methods).
:
:     *  A sender that is not cwnd-limited MUST NOT increase the cwnd
:        when ACK packets are received in this phase.

 + A general comment is that I find this document very hard to follow.
    There are forward references all over the place.  Can't this be
    simplified into a linear discussion of the algorithm?

: We will look at the possibility of reorganising the order of sections.

  + I think this:

      Reception of congestion feedback while in the non-validated phase
      is interpreted as an indication that it was inappropriate for the
      sender to use the preserved cwnd.  The sender is therefore
      required to quickly reduce the rate to avoid further congestion.
      Since the cwnd does not have a validated value, a new cwnd value
      must be selected based on the utilised rate.

    is exactly what RFC 5681 says.  I.e., it is why we changed things to
    be based on FlightSize.  I.e., it doesn't matter what is poked into
    "cwnd" at a given time, FlightSize is the load being imposed on the
    network and so that is the basis for the reaction to congestion.

    So, my reading of things is that RFC 5681 **already does** what you
    say you want in the above blurb.
: Except that Eqtn 4 in RFC 5681 does not consider the amount of losses

: during a congestion episode.
: If it was not validated, we argue that FS may be much
: larger than actual capacity and hence the "-R" reduction is important.

    And, yet, you go off and sketch a
    different reaction.  That may be fine, but you should at least
    sketch why the current standard is not germane here and why we need
    to go invent some new reaction.

    This is the sort of thing that makes this entire algorithm feel
    ad-hoc.  It reads like you didn't realize what already exists and so
    you invent new things.  I know that to not be the case, but that is
    exactly how this document comes off.

: We'll look again.

  + You claim this is a "safe" cwnd in response to congestion:

       cwnd = (Max(pipeACK,LossFlightSize))/2.

    But, let's think about that for a moment.  Say LossFlightSize is X.
    And so we took a loss (congestion) when imposing a load of X.  And,
    we know that cwnd can be up to 2*X at this point.  So, pipeACK could
    also be 2*X (from three RTTs ago, say).  So, after running the above
    we could have a cwnd of LossFlightSize---which is the load imposed
    when we observe congestion.  So, we could see no effective change in
    the imposed load.  Is that "safe"?  Is no reduction in sending rate
    "safe"?  I would minimally expect a discussion of why this is to be
    viewed as "safe" when it seemingly flies in the face of the way we
    have worked congestion control for a long time.

    And, yes, you further reduce FlightSize or pipeACK by R.  But,
    consider the case where R=1.  It hardly matters.

    (Note, I have purposely sketched the bounds cases.  Certainly things
    may not be like this in every case.  But, we should think about the
    worst case for what is being proposed.)

: This is one of the main changes. We can call-out the main changes in
: in the intro. The cwnd change to allow twice the recent peak rate o
: of a flow provides enough room to send - whereas the current standard
: would collapse the window (and ssthresh) based only on what was sent
: in the last RTT.

: Now, your argument isn't quite true. Two things to recall:
: First, in the NVP pipeACK is by definition less than (cwnd/2).
: Hence this assignment ALWAYS reduced cwnd by at least a factor of 2.
: Second, indeed the FS can be very small in a burst during NVP, since
: it can vary from RTT to RTT. There is no risk of persistent
: congestion because the the pipeACK becomes invalid after this assignment.

  + Then there is this:

      The sender MUST then update cwnd to be not greater than:

            cwnd = max((1/2)*cwnd, IW).

      Where IW is the appropriate TCP initial window, used by the TCP
      sender (e.g. [RFC5681]).

      (This adjustment ensures that sender responds conservatively at the
      end of the non-validated phase by reducing the cwnd to better reflect
      the current rate of the sender.  The cwnd update does not take into
      account FlightSize or pipeACK value because these values only reflect
      historical data and do not reflect the current sending rate.)
    I don't understand this.  FlightSize is not "historical data".
    FlightSize is the amount of outstanding data ***at each instant***.
    If there is no unacknowledged data then FlightSize is zero.  If we
    have 15K of unACKed data then FlightSize is 15K.  The above text is
    just confused.

: The above text was already noted on the list to have been a
: truncated part of the previous version of the text. We already agreed
: to delete the last sentence.

I can't tell if newcwv is needed or sound or whatnot.  The document
needs to be a whole bunch better.  I am happy to extend the benefit of
the doubt and believe there are some improvements we can make to CWV.
But, this document didn't convince me of it.  And, if I suspend
disbelief I can't even figure out if the algorithm is particularly
appropriate as it is not well explained.

FWIW.
allman

: Fair enough, at this time we didn't see any specific changes to the
: algorithm, but a need for clearer rationale and a set of corrections.
: We plan to include these in the next revision.

_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Mark Allman <[email-masked]>
Date: Thu, 27 Feb 2014 12:21:45 -0500

> : We can and will note this in the intro.

It seems this is more than a quick note.  If 'rate limited' is different
From what RFC 2681 addresses then does that document still hold when a
sender is idle or application limited?  Or, do you somehow subsume those
periods, too?  I am not taking a position on any of this.  I am just
asking that the document be clear and precise on what problem it is
going after and where it sits relative to other documents in the space.

> : We will look at the possibility of reorganising the order of sections.

(Or collapsing them might work, too.)

> : larger than actual capacity and hence the "-R" reduction is important.

OK, but you do not argue for the -R.  And, if -R is important here is it
not important everywhere?  You should explain your choices here.

> : First, in the NVP pipeACK is by definition less than (cwnd/2).

OK, fair enough point ... this point was (is) lost on me.  Perhaps the
document, perhaps my sloppy reading.

> : We plan to include these in the next revision.

Just to be clear it seems to me this document needs "clearer rationale"
in a bunch of places (some of which may well overlap) ...

(1) The document should include a discussion of why the current
    standards (here I am thinking of RFCs 5681 & 2681) are not well
    suited to modern application behavior.

(2) Since you're proposing something more aggressive I'd think a
    discussion of not only why an application would want to be more
    aggressive, but also why it is reasonable to loosen the congestion
    controller to accommodate such applications.  (E.g., we would agree
    that an application that wants CBR = 1Gbps with no reduction ever is
    unreasonable.  So, applications don't always get what they want.
    What you are trying to do---it seems to me---is give the
    applications something that helps them out, but that is also
    reasonable congestion control-wise.)

(3) If you're going to strive to meet requirements then we should know
    what those requirements actually are.  (I am not sure you really
    need to do either.  But, if you're going to do one, do both.)

(4) The above is big picture stuff.  But, you should justify the
    mechanism, as well.  Don't just use magic constants without
    justification (or via fuzzy and ambiguous reasoning).  Don't just
    add aspects of the response (like the "- R" notion) by claiming they
    are crucial without explaining.  Etc.  The specifics of the
    mechanism should be rooted in the overall goals and TCP's standard
    behavior, it seems to me.  And, you should be able to spell that
    out.

allman