| Previous | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Warning: this page has a bundle of png and gif pictures; it will last a little if you have an slow Internet connection. | ||||||||||||||||||||||||
| Continuing with our study we will see now how one TCP flow and one UDP flow compete for network resources. The topology will be the same we used before but having two sources; one for TCP and another for UDP. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| It's a good idea to have a look to this scenario when one TCP flow or one UDP flow is being transmitted. TCP and UDP interaction generates oscillation in both flows when they are competing for network resources. As you see the share is almost fair with each flow trying to get 50% of the available bandwidth. What really occurs is that CBR sources was set at 0.95Mbps and it tries to keep its constant rate through UDP, and TCP, on the contrary, tries to use for itself the rest of the available bandwidth, just 1.05Mbps. Then shares are very close to 50-50%. | ||||||||||||||||||||||||
| But competition is unavoidable. When TCP backs off, UDP takes advantage and tries to control the available bandwidth; a peak results then. But inmediately TCP tries to test network resources increasing its bandwidth consumption and UDP cedes and enters in a valley. This cycle repeats again and again. | ||||||||||||||||||||||||
| Let's see now the system throughput. Exactly as before, the instant throughput is calculated dividing the bytes of each packet (1000 bytes) by the time required to send the packet. The system throughput is calculated dividing the total bytes sent up to a given time by the total time transcurred in seconds. The graph is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Here we can see better the loss episode in the TCP life. But finally both flows accomodate well and each one takes about 50% of the total available bandwidth. Despite some oscillation performance is very acceptable. | ||||||||||||||||||||||||
| Let's see how latency goes for this scenario; here we have the graph: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Well, this variable suffers a lot. For one TCP flow the latency was close to 73ms and for one UDP flow it was 14ms. Now it is like we got before when two TCP flows were competing. UDP was harmed because even with two UDP flows its latency never was higher than 18ms. If you compare TCP behavior with two competing flows with this scenario, we have to come to a conclusion that UDP carries the worst thing in its interaction with TCP. It lost more. | ||||||||||||||||||||||||
| Let's check jitter; the graph is this: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| We have a large dispersion this time. Even worst than when two TCP flows are competing. | ||||||||||||||||||||||||
| Now is time to see what happen with total bytes transferred; for TCP we have: | ||||||||||||||||||||||||
|
KB sent: 1150.742188 |
||||||||||||||||||||||||
| And for UDP: | ||||||||||||||||||||||||
|
KB sent: 1148.437500 |
||||||||||||||||||||||||
| Total bytes transferred are then: | ||||||||||||||||||||||||
|
KB sent: 2299.180288 |
||||||||||||||||||||||||
| For UDP observe that total bytes transferred is exactly the same than before when two UDP flows were tested. We don't have in this case de-rating for UDP. TCP is almost the same too. When two TCP flows were competing in this scenario partial bytes transferred were 1109KB and 1069KB. Now we have 1150KB, even better. Great loser here is then UDP because its mean latency and jitter were seriously damaged. | ||||||||||||||||||||||||
| Finally let's check losses; for TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Very bad; this result is even worst than we got before when testing two TCP flows. | ||||||||||||||||||||||||
| For UDP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Eureka!! Exactly the same response than before with two UDP flows competing. In this new competition TCP lost more packets and UDP lost its very low latency and jittering. But I think UDP lost more. Because UDP is designed to be a very lightweight protocol for real-time traffic that is very sensible to high latencies and jitters. Having higher values of these variables spoils UDP reason to be. | ||||||||||||||||||||||||
| Okay, now we are going to make new tests selecting small packets of 100-byte size instead of packets of 1000-byte size. The instant throughput graph is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| New smaller packet size generates a denser oscillation. However, observe that again the bandwidth distribution is almost fair. Each protocol takes about 50% of the available bandwidth. Let's verify the system throughput: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Bandwidth distribution is very fair. UDP takes its predetermined fixed rate of 0.95Mbps and TCP takes all left available bandwidth, i.e., 1.05Mbps. Observe also that heavy TCP loss episode we saw before with 1000-byte size packets is not present this time. Smaller packets avoid serious conflicts and perhaps, we will check this later looking at the losses result, TCP saves itself now from having some dropped packets. | ||||||||||||||||||||||||
| It's time to see latency: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Well, a great improve using these small packets. 11.5ms is good enough even for real-time traffic. Also latency is very stable then we can expect a very, very low jitter. Let's check: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Really very good. Packet size reduction helps lowering significantly delay response. Let's check now the number of bytes transferred. For TCP flow we have: | ||||||||||||||||||||||||
|
KB sent: 1259.902344 |
||||||||||||||||||||||||
| And for UDP: | ||||||||||||||||||||||||
|
KB sent: 1148.144531 |
||||||||||||||||||||||||
| Total bytes transferred are then: | ||||||||||||||||||||||||
|
KB sent: 2408.046875 |
||||||||||||||||||||||||
| Okay. UDP bytes transferred are almost the same but we've got a better TCP response, just 9.48% more bytes transferred. Moving smaller size packets helps TCP to avoid a loss episode that affect its performance. | ||||||||||||||||||||||||
| Let's finish these tests checking losses. Here we have them for TCP flow: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Observe that packet size reduction dropped to zero TCP losses. Let's see if this improved behavior affected UDP negatively; losses in this case are: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Well, no. UDP maintains its good performance with no losses at all. | ||||||||||||||||||||||||
| Okay, fellows. We have seen how reducing the packet size has been beneficial for TCP response having no effects on UDP behavior. We have to suppose that increasing the packet size will be terrible, at least, for TCP. Let's check now this scenario. Next graph is instant throughput for 4000-byte size packets: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| It seems that both flows are having now a bad time. The graph shows even a worst scenario when it is compared with two TCP flows competing for network resources. Let's see system throughput: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| At a glance it seems that both flows are having losses now. We will check this below having a look to the loss results. Latency should be terrible in this scenario; the graph is this: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| It's true. It climbed up almost to 350ms. And now we have jittering. The graph for jitter is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| We have a band reaching up to 30-50ms. It's proved again than having bigger packets more latency and jittering is induced. | ||||||||||||||||||||||||
| Let's see now the number of bytes transferred; for TCP we have | ||||||||||||||||||||||||
|
KB sent: 1286.210938 |
||||||||||||||||||||||||
| More bytes transferred but probably we have losses in this scenario; for UDP we have: | ||||||||||||||||||||||||
|
KB sent: 1101.562500 |
||||||||||||||||||||||||
| UDP suffered more than TCP. Number of bytes transferred are now 4.09% less. Total bytes transferred are then: | ||||||||||||||||||||||||
|
KB sent: 2387.773438 |
||||||||||||||||||||||||
| Number of bytes transferred is a little bit more than when using 1000-byte size packets. We have an increase of 3.85%. Despite of the observable loss episodes, using larger size packets we improve our system throughput. | ||||||||||||||||||||||||
| Finally, let's check losses in each flow; for TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| and for UDP: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| As you see UDP took the worst piece of the pie in this sharing. | ||||||||||||||||||||||||
| Next step in our investigation will be to see what happen when the link bandwidth is reduced having the two flows competing for resources. How TCP will react? UDP will be receiving packets almost to the link bandwidth capacity practically leaving no availability for TCP. Will TCP support this scenario? We will adjust the link bandwidth to 1 Mbps instead of the original value of 2 Mbps. The propagation delay will be kept in 10ms. Here we have the instant throughput for this case: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| TCP can't support this scenario; its starvation is clearly observable. It tries to recover but falling is unavoidable. Let's see system throughput: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| In this graph TCP starvation is better observed. Final throughput is in the 100kbps range. It can't fight against UDP to preserve some significant share of the total available bandwidth. | ||||||||||||||||||||||||
| Let's see how latency behaves for this environment: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Both seriously spoiled. UDP is in the range of 200-240ms, some really unacceptable for real-time traffic over UDP. TCP is even worst. It has some episodes with packets delayed up to 4 seconds and even more. | ||||||||||||||||||||||||
| Jittering should reflect this situation; let's have a look to it: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Some week dispersion but having deviations up to +/- 80ms. | ||||||||||||||||||||||||
| Next we will check the total bytes transferred for each flow; for TCP we have: | ||||||||||||||||||||||||
|
KB sent: 92.460938 |
||||||||||||||||||||||||
| Really terrible for TCP. UDP starved it to having less than 10% of the total available bandwidth. | ||||||||||||||||||||||||
| For UDP we have: | ||||||||||||||||||||||||
|
KB sent: 1133.789062 |
||||||||||||||||||||||||
| UDP almost maintained its original throughput (having a 2Mbps link) of 1148 KB sent, a reduction of only 1.31%. | ||||||||||||||||||||||||
| Let's see what about with losses; for TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Packets sent suffered a reduction of 89.64% from 1158 packets to just 120 packets but indeed number of dropped packets climbs to an unacceptable value of 23.33%. | ||||||||||||||||||||||||
| For UDP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| In this case number of packets sent are the same but we have small losses of 1.28%. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Well, again some additional buffering serves to relieve pressure against traffic. Now curves are soften and less oscillation is present. Share is fair having UDP its 0.95Mbps and TCP the available bandwidth left. | ||||||||||||||||||||||||
| Let's check the system throughput. The graph is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| TCP has better performance in this scenario. The heavy loss episode when flow was starting using 20-packets buffering has disappeared. Let's check if latency was hardly affected; the graph is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Well, latency is a little higher now but very stable. Let's check queues for both scenarios; for 20-packets buffering is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| It seems that sometimes total number of packets are very close to the limit. Let's check the total queue (both flows): | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Yes, very close. Buffer is almost full most of the time. Let's check now queues for 50-packets buffereing: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Now. again, response is soften. But total queue reaches almost 30-packets. This means that original 20-packets buffering was not good enough for our scenario. Let's check total queue (both flows): | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Very nice. Buffer is filled most of the time with 32-33 packets. Minimum buffering should be at least 35 packets for this scenario (two flows, TCP + UDP). | ||||||||||||||||||||||||
| Of course, having a longer queue implies a higher latency. But in this case is better because we have less pressure against the flows, perhaps no losses (we will check this below) and an improved response at all. | ||||||||||||||||||||||||
| Jitter should be almost zero because latency is very stable; the graph is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Small peaks and valleys in the latency graph above are responsible for this jittering that oscillate between +/- 4ms. Nevertheless, this behavior is a little bit better than it was obtained using a 20-packets buffer. Extra-buffering helps to have an smoothed response. | ||||||||||||||||||||||||
| Okay, it's time to check the number of bytes transferred; for TCP we have: | ||||||||||||||||||||||||
|
KB sent: 1298.007812 |
||||||||||||||||||||||||
| Very well!! An improve of almost 13% when comparing with a 20-packets buffer test. Just again having the right buffer helps to have even an improved throughput. | ||||||||||||||||||||||||
| For UDP we have: | ||||||||||||||||||||||||
|
KB sent: 1148.437500 |
||||||||||||||||||||||||
| Exactly the same response we got before using an smaller buffer. We can conclude that mainly for TCP a right buffering selection is very important to have a better tunned system. | ||||||||||||||||||||||||
| Finally let's check losses for this environment; for TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Definitively TCP took advantage from the higher buffering. Now it sent more packets (10.45% more) and it didn't have losses. For UDP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Same number of packets sent with no losses again. | ||||||||||||||||||||||||
| Okay, fellows; it has been proved that selecting a right buffering is very important to get as much as is possible from your system; then, it is self-evident that having the opposite, i.e., not enough buffering should be hardly bad for the system; let's check this. Using an under-buffering scenario of 5-packets we have the following instant throughput graph: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| First, we have less output. Using 20-packets buffer peaks reach up to 1.8Mbps. Now they have a top of about 1.25Mbps. However share "seems" as being fair as before. Let's see the system throughput: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Well, share really is not fair. Soften with EWMA tends to generate some distorsion of the reality when reading instant throughput, but system throughput gets back us to the real scenario. TCP has been starved again, now not as severely as was before when having a 1 Mbps link but phenomenon is clearly observable. Final TCP bandwidth oscillates about 250Kbps, i.e., 25% of what it should be. On the contrary UDP kepts its share. Again as before, reducing the queue's buffers we have a less fair environment, this time affecting more severely to TCP. | ||||||||||||||||||||||||
| Let's have a look to latency for this scenario: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Latency is lower than it was when using a 20 packets buffer. It is also more stable. Very similar to what we got before with two TCP flows competing. Packets are now having to make less queue in buffers. Let's check jitter this time: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Some dispersion but centered on zero axis. We will check below how having this little improve in latency and jittering will affect bytes transferred and losses. But let's check previously our queues. Do you remember the 20-packets buffer queue? It was: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Both flows oscillates about 6 packets. Now that we have only 5 packets as buffering how will this graph look; let's see: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Queues are now very constrained and each flow seems to have no more than one packet in queue. Let's check how all this affect number of bytes transferred. For TCP we have: | ||||||||||||||||||||||||
|
KB sent: 282.382812 |
||||||||||||||||||||||||
| Terrible!! This value is 75.48% less than we got using a 20-packets buffer. TCP was hardly starved in this scenario. For UDP we have: | ||||||||||||||||||||||||
|
KB sent: 1148.437500 |
||||||||||||||||||||||||
| On the contrary UDP have maintained exactly the same number of bytes transferred. Reducing the buffer only affected TCP behavior. Observe that total bytes transferred are now: | ||||||||||||||||||||||||
|
KB sent: 1430.8203 |
||||||||||||||||||||||||
| And we have now our link bandwidth under utilized. | ||||||||||||||||||||||||
| Finally let's check losses; for TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| We have not only a lot of less packets sent (1158 packets before vs 304 packets now) but losses increase from 2% to 8%. A very bad response for TCP. For UDP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| No de-rating for UDP. Same number of packets with no losses. | ||||||||||||||||||||||||
| TCP starving is the main decision here. Buffer reduction was not convenient because marginal latency and jittering reduction is unjustifiable. Then, as long as we are talking about TCP it is better to have enough buffering to avoid starving. Issue is then trying to find the right choice to have enough buffering without increasing too much latency and jittering response. | ||||||||||||||||||||||||
| Our last test will be to see what happen when we select a propagation delay of 100ms instead of 10ms, almost a ten times longer link. The instant throughput is: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| We have an scenary very similar to what we got before using a 50-packets buffer. Oscillations are soften now. Something we can expect because having a longer link is like having more buffering available for packet allocation. But beware, let's check system throughput to be sure EMWA is not making some tricks; here we have: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Okay, but just again, TCP is carrying with the worst behavior. We saw before that TCP is more sensible to longer links than UDP showing for these scenarios more oscillations and a poorer response. On the contrary UDP seems to be as being in home. | ||||||||||||||||||||||||
| Let's see latency: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Well, at least 100ms of this is due to the link propagation delay. There is more dispersion now. We can suppose as before than the queue was translated from the buffer to the link. Let's have a look to the queue graph: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Confirmed!! Now the queue is very low. Packets are now traveling very happy throughout the link. Let's have a look to the jitter to see how this dispersion influence its behavior: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Okay, it's time to check losses. For TCP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| Okay, no losses because longer link implies a higher buffer to receive packets and soften oscillations but paying with a reduction of about 22.4% in the number of packets sent with TCP. For UDP we have: | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| UDP is very fresh drinking a glass of delicious juice because its response is exactly the same. Same number of packets with no losses. | ||||||||||||||||||||||||
| It's time to repeat again what we said before and before. Conclusions are the same, i.e.: | ||||||||||||||||||||||||
| Comparing both protocols, UDP surpassed in most of the tests to TCP. TCP is deeply affected by many factors like available bandwidth, network congestion, buffering availability, link propagation delay, packet size, interaction with other flows and protocols, bad luck at startup, etc., etc. UDP is stronger because it is simple and of constant rate by nature. Problem to select UDP instead of TCP as a viable Internet transport protocol is how to control losses when the network get congested. | ||||||||||||||||||||||||
| If we could have a controlled network where Call Admission Control (CAC) could be implemented, and if we could shape UDP traffic to be sure it respects the initial solicited bandwidth, then UDP would be a very nice solution for traffic transport. But, because this ideal conditions can't be implemented yet in Internet, and being the main goal to protect the health of the network against congestion disease, the only solution is to run it with the safer TCP. | ||||||||||||||||||||||||
| Okay, that's all folks. Hoping this document can be of some usefulness for you in your daily work. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Previous | ||||||||||||||||||||||||