
On 8/8/2012 2:06 AM, Mo Zanaty (mzanaty) wrote:
Just to make sure I understand your "bonus" reduction, it is because the "fishy" pattern confirms a congestion loss rather than a possibly stochastic loss, right? Or is there another reason to apply the bonus that I missed? Like some sort of mild congestion vs. severe congestion inference (that can't be obtained by the loss signal itself alone)?
Mostly it was just stronger confirmation of congestion, and it seemed to work well. It increased the chance that in the first adjustment after congestion is noticed we'd be below the available bandwidth and the queues would start to drain (and drain faster!) - but the downside is that if the loss isn't congestion, you would impair quality more, which is why it was limited to cases where I was pretty sure. This brings up a related point - reaction speed. I've proposed here using the slope output of the filter to adjust the amount of bandwidth reduction. It's a fairly simple argument: * The slope of delay increase is directly proportional to how fast the queue is growing. * The rate the queue grows is directly proportional to how far over-bandwidth the bottleneck is * You want to reduce bandwidth far enough to cause the queues to start to drain. Note that in (3), it's really the combination of your reduction and the reduction of any other streams sharing the bottleneck. Once again, this argument is strongest when there are few streams at the bottleneck. In the single stream case, if you have correctly determined the slope, if you reduce bandwidth by an amount directly proportional to the slope, then you will (in theory!) exactly hit the link bandwidth. You'd want to slightly overshoot on purpose to ensure draining of the queue buildup. As the number of competing streams increase, you're more likely to over-react, in that you're reading the bottleneck over-use amount, but you're only responsible for one of the flows. So you have to be careful... On the other hand, you want to get the bottleneck below congestion as fast as possible to avoid further delay buildup, and you want to overshoot slightly to ensure it drains (especially if another flow is still increasing (TCP sawtooth)). So, instead of trying to hit the target in a single reduction, you can instead reduce sending rate by a fraction of apparent over-bandwidth amount (with some minimum reduction amount or percentage). This means in the single-flow case, it will take several RTT at minimum to get below the link rate, but the delay increase rate will continually slow. With this slower reaction pace, you want to also stop reacting more slowly, to ensure you get into the queues-draining point, and drain them fast enough to make a difference. You can do this by a number of methods. When the filter confirms the draining is occurring, you'll want to wait to increase bandwidth until the queues are stable and hopefully drained (the current algorithm includes this). This has the advantage of reacting faster in cases of more severe congestion or larger over-link-bandwidth cases. Tuning the reaction rate for sharing the link with other RRTCC flows, and to share reasonably with TCP flows would be the subject of tests; there are other related values to tune it, such as for how long it avoids switching direction (decrease->increase), how it reacts during startup, how RTT and jitter in delay signals feed in (more jitter may imply more competing streams, but not always). You *might* be able to infer the number of competing streams (or some measure of competition) by the slope change after a reduction. In the single-flow case, it may be a fairly strong signal that it's single-flow, and you might want to include memory of that for a period and adjust the reaction rate to be faster. One reason single-flows are so interesting is that access-link congestion is a very common case and very important case for connection quality for the user, if not the worrying case (from congestion-collapse or fairness perspectives). -- Randell Jesup randell-ietf@jesup.org