Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Mar 2003 19:37:10 +1100
From:      Peter Jeremy <peterjeremy@optushome.com.au>
To:        David Cuthbert <dacut@kanga.org>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: first parameter to select
Message-ID:  <20030313083710.GA8225@cirb503493.alcatel.com.au>
In-Reply-To: <3E702BCC.3030208@kanga.org>
References:  <3E702BCC.3030208@kanga.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 13, 2003 at 01:57:16AM -0500, David Cuthbert wrote:
>To be honest, I've never passed anything but FD_SETSIZE for this 
>parameter.  When I'm writing a performance critical server, I use poll() 
>instead.  It's faster

This is an interesting claim.  Do you have some pointers to back it up?
It would seem to be rather unreasonable to claim that poll() is faster
when (by your own admission) you've never used select() efficiently.
I could equally say that I always pass getdtablesize() as the second
argument of poll() and if I'm writing a performance-critical server,
I use select() instead - it's faster.

Effectively, the difference between poll() and select() is that poll()
uses an array with each element representing one file descriptor
whereas select() uses 1-3 bit arrays.  The underlying function to
test each FD within the kernel is the same in both cases (fo_poll()).
Any performance differences are therefore due to:
(1) The amount of data crossing the userland<->kernel barrier
(2) The time to scan the data to locate FD's of interest.

poll() optimises (2) at the expense of (1) - each FD requires 8 bytes to
be passed in and out of the kernel.

select() minimises (1) at the expense of (2) - though the actual
behaviour depends on the sparseness of the file descriptor sets (and
correctly setting nfds).  The FreeBSD implementation will also be less
efficient where the same file descriptor is set in more than one of
the FD sets.

In virtually all cases, poll() will need to copy more data in and out
of the kernel then select() would.  Likewise, in virtually all cases,
select() will need to scan more file descriptors than poll() does.
The overall performance comes down to the relative cost of copying
data vs testing bits.

> and I don't have to reinitialize the fd_set 
>bitmasks on each iteration.

This is 'convenience', not performance.  And this is offset by the
increased cost of updating the pollfd array when a connection is
closed.  I've found that in most of the servers I've written, the
actual events you need to test varies from iteration to iteration
in any case (eg you don't want to test for writable unless there
is currently some data to write).  I usually wind up scanning through
an internal list/array of connection structures/objects and creating
the fd_sets or pollfd array on the fly.

>  It's technically less portable, but I've
>never had an issue across Solaris, HP-UX, Linux, or FreeBSD. 

select() is the older mechanism, developed for BSD.  poll() is the
SystemV equivalent - and is therefore blessed by SVID etc.  (My guess
is that the API difference is more due to NIH than any technical
justification).

Peter

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030313083710.GA8225>