1 Increase: W = W + --- (when new ACK is received) W Decrease: W = W - 0.5 * W (when packet loss is detected by 3 dup ACKs) |
|
What value of CWND used by TCP will yield the average TCP throughput:
1 1.2 Avg TCP Throughput = ----- * ------- (in # packets/sec) RTT --- \/ p
|
1.2 Avg. CWND = ------- (in # packets) --- \/ p |
(= 2/3 * W) Packet Drop Rate P Congestion Window W RTTs Between Losses ------------------ ------------------- ------------------- 10^-2 12 8 10^-3 38 25 10^-4 120 80 10^-5 379 252 10^-6 1200 800 10^-7 3795 2530 10^-8 12000 8000 10^-9 37948 25298 10^-10 120000 80000 Table 2: TCP Response Function for Standard TCP. The average congestion window W in MSS-sized segments is given as a function of the packet drop rate P. |
This CWND value will NOT allow TCP to transmit at Giga bits per sec |
a Increase: W = W + --- W Decrease: W = W - b * W ------------ 1 / a (2 - b) Avg TCP Throughput = ----- \ / ---------- (# packets/sec) RTT \/ 2bp |
------------ / a (2 - b) Avg TCP CWND = \ / ---------- (# packets) \/ 2bp |
(RTT is not an unknown, it can be measured by the TCP connection)
That means that we can choose the value of 3 unknowns (i.e., parameters) and the value of the 4th unknown is fixed
|
|
In other words:
|
In other words, when a High speed version of TCP and a "normal" (Reno) TCP compete for bandwidth over a common bottle neck link, the "normal" (Reno) TCP must be starve for bandwidth We call this property: "TCP-friendly" |
|
|
![]() |
(Avg. Throughput is then: 83,000x1500x8/0.1 = 9,960,000,000 bps or about 10 Mbps) For High_Window set to 83000, we specify (i.e., our guess) High_P equal to 10-7; that is:
We believe that this loss rate sets an achievable target for high-speed environments, while still allowing acceptable fairness for the HighSpeed response function when competing with Standard TCP in environments with packet drop rates of 10-4 or 10-5. (See Page 6 in "RFC3649: HighSpeed TCP for Large Congestion Windows") |
![]() |
|
This works out (see above) to a target CWND = 83000
For this best case scenario , they found values of TCP increase/descrease parameters a (e.g.: 72) and b (e.g.: 0.1) that will allow TCP's CWND to work its way towards the target CWND of 83000
|
Target packet drop probability = 10-7 Target CWND = 83000 |
------------ / a (2 - b) Avg TCP CWND = \ / ---------- \/ 2bp |
------------------ / a (2 - b) 83000 = \ / ---------- * 107 \/ 2b |
--------------------- / 72 (2 - 0.1) \ / ------------- * 107 \/ 2*0.1 ------------------ / 72 * 1.9 = \ / ---------- * 107 \/ 0.2 -------- / = \ / 684 * 107 \/ = 82704.29 (approximately 83000) |
--------------------- / 459 (2 - 0.5) \ / ------------- * 107 \/ 2*0.5 ------------------ / 459 * 1.5 = \ / ---------- * 107 \/ 1.0 -------- / = \ / 688.5 * 107 \/ = 82975.90 (also approximately 83000) |
That's 4590 packets in a second...
This could cause severe buffer overflow
That's 720 packets in a second...
This is obviously a much gentler solution
The choice they have made is: a = 72 and b = 0.1 |
![]() |
![]() |
0.12 W(p) = --------- . . . . . . . . . . . . . . (1) 0.835 p |
It is very obvious that TCP will use a very large CWND only when the packet drop probability is very low:
![]() |
it is a straight line going through the design points: (p=10-7, W=83000) and (p=10-3, W=38)
![]() |
Why it is a straight line on a log-log scale is obvious when we re-write the Interpolation function as follows:
0.12 W(p) = --------- 0.835 p |
Packet Drop Rate P Congestion Window W RTTs Between Losses ------------------ ------------------- ------------------- 10^-2 12 8 10^-3 38 25 10^-4 263 38 10^-5 1795 57 10^-6 12279 83 10^-7 83981 123 10^-8 574356 180 10^-9 3928088 264 10^-10 26864653 388 Table 3: TCP Response Function for HighSpeed TCP. The average congestion window W in MSS-sized segments is given as a function of the packet drop rate P. |
0.12 W = --------- 0.835 p |
a(w) Increase: w <- w + ------ w Decrease: w <- w - b(w) * w |
TCP knows exactly what w is.
------------------ / a(w) (2 - b(w)) w = \ / ---------------- (# packets) \/ 2 b(w) p |
Notice that there are ONLY TWO degrees of freedom in Equation (3):
The value p(w) is not really variable because it can be found by INTERPOLATION using Equation (2): click here
0.0789 p(W) = --------- W1.2 |
|
![]() |
Large fluctuations generally make a system unstable
To compensate (i.e., reduce) the larger fluctuations we make b smaller quickly
log(w) - log(38) b(w) = (0.1 - 0.5) * ---------------------- + 0.5 . . . . . (4) log(83000) - log(38) |
The Interpolation curve for b(w) looks like this:
![]() |
a(w) New ACK: w <- w + ------ w Triple Dup ACK: w <- w - b(w) * w |
We compute the parameter b(w) using the current CWND value w and the formula:
log(w) - log(38) b(w) = (0.1 - 0.5) * ---------------------- + 0.5 log(83000) - log(38) |
So if HighSpeed TCP performs a CWND decrease, this is all the TCP needs.
HighSpeed TCP must do a lot more:
0.0789 p(W) = --------- W1.2 |
log(w) - log(38) b(w) = (0.1 - 0.5) * ---------------------- + 0.5 log(83000) - log(38) |
2 w2 b(w) p(w) a(w) = ---------------- 2 - b(w) |
Look for the method "double TcpAgent::increase_param()".
Here is a "cleaned up" code segment of the HighSpeed TCP algorithm:
# These are all used for high-speed TCP. Agent/TCP set low_window_ 38 ; # default changed on 2002/8/12. Agent/TCP set high_window_ 83000 Agent/TCP set high_p_ 0.0000001 # 10^-7 Agent/TCP set high_decrease_ 0.1 Agent/TCP set max_ssthresh_ 0 double TcpAgent::increase_param() { double increase, decrease, p, answer; // p ranges from 1.5/W^2 at congestion window low_window_, to // high_p_ at congestion window high_window_, on a log-log scale. // The decrease factor ranges from 0.5 to high_decrease // as the window ranges from low_window to high_window, // as the log of the window. // For an efficient implementation, this would just be looked up // in a table, with the increase and decrease being a function of the // congestion window. if (cwnd_ <= low_window_) { answer = 1 / cwnd_; // Standard Reno return answer; } else { // hstcp_.p1 = log(hstcp_.low_p) // - log(low_window_) * highLowP/highLowWin; // hstcp_.p2 = highLowP/highLowWin; // hstcp_.dec1 = 0.5 - log(low_window_) // * (high_decrease_ - 0.5)/highLowWin; // hstcp_.dec2 = (high_decrease_ - 0.5)/highLowWin; p = exp(hstcp_.p1 + log(cwnd_) * hstcp_.p2); decrease = hstcp_.dec1 + log(cwnd_) * hstcp_.dec2; increase = cwnd_ * cwnd_ * p /(1/decrease - 0.5); answer = increase / cwnd_; return answer; } } |
![]() |
![]() |