title: tcp or udp, another comparision
body: <p>Consider a cache application with thousands of requests per second where the client asks for an object using an integer index and the server sends the object back to it. (Linux only)</p>
  
  <p>What would be faster for an UDP protocol:</p>
  
  <ul>
  <li>Send multiple replies in a single packet?</li>
  <li>Send a single reply in one packet?</li>
  </ul>
  
  <p>(applicable for both sides , server or client)</p>
  
  <p>Disadvantages:</p>
  
  <ul>
  <li><p>Multiple replies per packet:</p>
  
  <ul>
  <li>many memcpy()s will be needed to assemble packet with multiple replies. If a get() request returns to the client 16 byte objects, a single packet of 65535 bytes would have to memcpy() about 4000 objects before issuing sendto() system call. <em>memcpy() is costly</em></li>
  <li>An UDP packet of 65000 bytes will generate about 43 udp packet headers
      since the packet will be transmitted in fragmetns, due to 1500 default MTU size. <em>not a big overhead</em></li>
  </ul></li>
  <li>Single reply per packet:
  <ul>
  <li>every get() will result in 28 bytes of protocol overhead. For an object of 16 bytes this will be costly. The throughput of objects per second will be low and <em>network will be saturated with packets</em>. For example, sending 4000 objects will generate 4000 udp packet headers, condierably more than 43 headers with multiple replies. </li>
  <li>Also, too many sendto() syscalls will <em>increase CPU consumption</em> becase the kernel has to save CPU registers on each syscall.</li>
  </ul></li>
  </ul>
  
  <p>It appears that both methods have their disadvantages and it is not clear which solution will be better, however, the clock of gigabit ethernet runs at 1GHz while the processor is for example 3 GHz also the memory
  bus is much wider than the twisted pair of the ethernet interface. So, multiple replies
  per packet would be better choice since the extra memcpy()s will reduce network traffic, correct?</p>
  
  <p>Now, if we use TCP instead of UDP:</p>
  
  <ul>
  <li>Multiple replies per packet:
  <ul>
  <li>again, many memcpy()s will be needed to assemble the packet, which shouldnt be larger than 65535 and then it would be fragmented by the kernel to send it in packets of size of the MTU <em>not much difference as with UDP here</em></li>
  </ul></li>
  <li>Single reply per packet:
  <ul>
  <li>Since our 16 byte objects are distributed randomly in server's memory, we will have to issue a write() syscall per object, <em>the same number of syscalls as with udp</em> single request case.</li>
  <li>every get() will result in 52 bytes of overhead due to that TCP has larger header +
  we will have to another overhead of ACK packet which is abour 40 bytes. <em>even bigger network traffic</em></li>
  </ul></li>
  </ul>
  
  <p>Conclusion:</p>
  
  <ol>
  <li>For this particular application (sending simple data chunk to the client from an index given by the client) <em>TCP will not perform any better than UDP</em>. + consider that the implementation of TCP stack is much more complicated than UDP, more instructions are executed there. <strong>The whole point for making the protocol to run faster is to assembly UDP packets as large to the MTU as possible</strong>.</li>
  <li>The cost of adding another NIC to the system is lower than adding another CPU. It makes sense to go for lowering the number of memcpy()s but send a bunch of small UDP packets and pay extra for the overhead of each udp header on the network side (+ some little more overhead by doing many sendto() syscalls which i think will be lower than memcpy()'s overhead) because this way with one CPU could send requests over many NICs</li>
  </ol>
  
  <p>Will greatly appreciate your comments and your experiences on the choice of protocol.</p>
  
  <p>Note:
  lets set aside the reliability issues and assume our networks are error free, which is
  most of the time true if you wire them correctly, and if an error occurs it is certainly not the norm</p>