Re: Socket switch delay

From: mil (mil_at_discussions.microsoft.com)
Date: 08/21/04


Date: Sat, 21 Aug 2004 02:43:01 -0700

Thank you for writing such a detailed reply. Before I answer your points, I
will answer your question first:

The server (as I mentioned) makes full use of CompletionIO (multiple threads
using ‘GetQueuedCompletionStatus’). It uses it for socket input/output and
file read/write.

When a client wants to read a file, it sends a “resolve/open” request to the
server and then multiple “read-segment” requests. These requests are queued
and processed asynchronously like the rest of the packets. So a sckt-input
completion packet generates a file-read/write completion packet, then that
generates a sckt-output completion packet.

Using this method I am not “touching” the files, the OS does all the work,
schedules extra threads etc (as you know) and I can say it really works! MS
has done such an amazing job with the CompletionIO that I was amazed by the
speed, smoothness and scalability of the whole thing.

When using slow connections and the server is heavily loaded, I want the
client to be able to execute multiple read/write requests. For example when
writing a file it can issue 3 write requests for 64KB then wait for the
replies (i.e. It sends one segment, the server starts writing the segment to
the file asynchronously, while the client is sending another segment).
If the server completes the file segment write, then it sends a reply, but
the client is not blocked waiting for each reply. At a given point (after it
has sent X segments) it blocks and waits for all the of them to be completed
by getting all the replies from the server.

What I am achieving essentially is a send/write concurrency, thanks to the
CompletionIO.

If I use one socket I cannot send and receive at the same time (or am I
doing something wrong in the sockets setup???), so I will have to send a
segment, wait for the reply, send another. So essentially the client is
waiting for the server to write the segment to the HD before it gets the
reply.

If I use 2 sockets then the client can be sending segments with the master
thread, while another thread is receiving replies. Then the master thread
blocks till all the replies are gathered.

> The delayed ACK algorithm says that ACKs should be sent only

So essentially with 1 socket, because it is used for sending and receiving,
I “cancel” the delayed ACK 200ms wait, by simply using the same socket to
send the reply.

Based on that observation, if I was using 2 sockets and I was sending &
receiving to/from both, I would not get “penalized” with this delay (?)

When I am sending data, I use the multiple-buffers-send capabilities of the
WSASend function and a 0 bytes send-socket-buffer. When receiving I have let
the socket use a big buffer of its own to hold the whole message (most of the
times).

But most of the requests the client sends are small packets, so unless the
receiver uses the same socket to also send replies back, it will keep waiting
for more data (for up to 200ms).

I assume there is no way to change that, or “inform” the recv that I know
how much data I am waiting for etc. so essentially if I want to create the
concurrency scenario I described at the beginning I will have to redesign the
whole thing, something like having the server postpone sending the replies or
something, so the client can send >1 requests etc…

mil


Loading