This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Performance: fhandler_socket and ready_for_read()


Attached is a socket patch that can make some programs by as much
as 50 times quicker.

In looking for something else, it struck me that there doesn't
seem to be any reason for the fhandler_base::ready_for_read()
method when reading from sockets.  All that the method seems to be
doing is checking for signals while waiting for data to arrive on
the relevant fhandler object (eventually it calls peek_socket()
which does a select() on the socket).  The fhandler_socket::read()
method already handles signals happily (if the socket is blocking
and winsock2 is available) since it uses an overlapped read and
then blocks on the socket event and the signal_arrived event.

Assuming that there is thus no need for this call to
ready_to_read() for sockets (and please tell me if I'm wrong
here), the following patch provides an stubbed
fhandler_read::ready_for_read() that does nothing when that is
valid.

In testing "transactional" programs, i.e. where one program writes
a message then reads a reply, I've seen speedups of between 3 and
50 times :-)  Goody, goody!

The 3 times quicker is for applications that have a connection per
transaction, where the connection set up and tear down dominates
the times.  The 50 times quicker is for applications that have one
connection and read/write zillions of messages to each other.
Applications that are not transactional, in this sense, are
(generally) unaffected by this patch.

I've found one situation where a (test) program is slower *with*
this patch.  I've got test programs that read and write 1Mb
messages between each other.  If they use small buffers (e.g. 1Kb)
or v. large buffers (e.g. 1Mb), they run at the same speed with or
without the patch.  On the other hand, if they use intermediate
sized buffers (e.g. 64Kb), they run twice as slowly *with* this
patch.

The reason for this seems to be that the WSARecv returns as soon
as there is any data available.  With the current (heavy)
ready_for_read() implementation, there is time for the socket
buffers to fill/empty (as appropriate) leading to fewer calls to
WSARecv().  To test this, I added a Sleep(0) into the test
programs before each call to read(2) and, lo and behold! they then
performed as well as they had w/o the patch.

I assume then that this slowdown will not affect many programs,
since most will be doing something with all the data and so will
not trip over this.  Even if they do, I would have thought that
the patch is worth it's salt.

Anyhow, enjoy!

// Conrad

p.s. This patch is independent of my UNIX domain socket patch.

Attachment: ChangeLog.txt
Description: Text document

Attachment: ready_for_read.patch.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]