select vs poll

Hi,

Off late I had been looking at the differences b/w select() & poll() system calls. The requirement is to reduce the overhead, processor power in waiting for the data. In the kind of connections under consideration there would be very frequent data arriving on the sockets, so poll() fares well.

But!!! Even in the few millisec when the data is not arriving, the application can do something better! So will select() be a better function to go for?

In that case will there be any performance improvement at all?

Instead, is there a scope for some kind of asynchronous call back functions where the appliction will just be initimated in case data arrives.

On the whole, the requirement is that unnecessary waiting time should be cut & perfromance improved!

If this is not the right forum, can somebody suggest the right one.

Thanks in advance!!!

In many cases the choice is made for you.

If the system is BSD derived, then use select. In this case poll is merely a wrapper around select.

If the system is System V derived, then use poll. In this case select is merely a wrapper around poll.

The main advantage of poll is the number of file descriptors is not limited by the size of fd_set, other than that there is no real difference.

Just because you can specify the time in microseconds or nanoseconds does not mean the OS will honour those, they are still limited by the system/heartbeat clock frequency.

Hi,
I dont know which platform your are working on. But of the query,

I guess for solaris 10 (Sun OS 5.10), there is a new amenity called "Completion Ports". I wonder if this may be useful for you. I dont have much background on this feature. But on quick glance at it, I guess it is a type of asynchronous request handler.

Excuse me if the information is misleading/away from the topic...

Thanks
Srini

Hi,

Srinivasan: Thanks for the information. That was exactly something I was looking out for. Do you by any chance have any idea about how much performance improvement can be achieved by replacing poll with Asynchronous I/O framework.

Porter: How do I check if my system is BSD derived or V derived?

/smanu.

There are a number of ways but here we are trying to find out if select or poll is the more fundamental call. A suggestion is to look at sys/syscall.h and see if SYS_select or SYS_poll exist. If both exist then *maybe* both are native, but for instance not in the case of Darwin. In that case you could check to see which is the "earlier" call, ie if SYS_select is less than SYS_poll.

Ok! My syscall.h has got SYS_poll only.
So poll() seems to be the primitive one.

But could you tell me what are those other number of ways in which we can check if our system is BSD derived or V derived?

Off the top of my head the three main differences for a programmer are:

  1. STREAMS

if has #include <sys/stream.h> it's SYS V

  1. signals

if it has sigblock & sigsetmask it's BSD, if sighold & sigrelse it's SYS V

  1. terminal handling

check prototype for "setpgrp()", if takes two args it's BSD

But as systems have all adopted BSD sockets and merging to standardisation on posix compatibility it is more important to check the actual feature you are trying to use.

Alternatively consider pthreads. If your application takes advantage of threads for concurrent activity it will scale better on SMP hardware.

You sure don't mention many details. Not even which OS you use. "Connections"... so you are awaiting connections from a listen(2)? How many fd's are involved? Lots of connections to lots of fd's is a different problem than lots of connections to a few fd's.

For lots of fd's, select/poll bogs down because massive structures to describe the fd's must be copied between user/kernel space. This is one of several problems addressed be the epoll facility which I have only seen in Linux. (But note that fd_set can be large with modern implementions. People need to stop assuming it is an int!)

Lots of connections to a few fd's can be addressed by not allowing select to get involved with every connection... instead drain the listen queue on the first select. This paper argues that when select(2) returns, accept(2) should be called in loop until it gets EWOULDBLOCK. The authors describe a considerable performance boost. You might want to try this... I thought it sounded very interesting.

Or are you reading and writing on established connections? Assuming your OS has a decent thread implementation, I would try one thread per socket in each direction that data flows.

You ask about asyncronous I/O. Traditionally this is a problem if more than one fd is involved since there is only one SIGPOLL signal to deliver to a process. Sure, you can get the signal and then do poll(2)/select(2) but this is only useful for very sparse data arriving on multiple fd's. And now with threads, perhaps it is not useful at all. Posix defines some new async i/o stuff, but your OS may not have and I have never used the new stuff.

My OS is Solaris 9. But I can also try experimenting on Solaris 10 & if there is any real performance boost, don't you think it would be possible to implement the equivalent things on Solaris 9?
I shall provide more info on no. of connections & fd's tomorrow.

Rarely does merely switching versions give you a huge performance boost.

I suggest you look at your application architecture and look for bottlenecks.

  1. Do you use non-blocking sockets?

  2. Do you use threads?

  3. Do you parallelise concurrent activity?

  4. Do you have large global locks/mutexes?

  5. Does your program support SMP?

I guess, I made my statement ambiguous. I mean: I shall experiment asynchronous I/O, the new feature introduced in Solaris 10 & if that improves perfromance, implement the equivalent stuff in Solaris 9.

Now my question is: shouldn't replacing the synchronous calls with asynchronous ones improve the performance?

What is performance? Speed of handling a single client connection or total system throughput? You may find one is a trade off against the other.

Also, increasing performance may increase the complexity, robustness and maintainability of your application. It's your decision.

Threads are far easier to manage correctly than signals.

Ironically one way to improve system performance is to make applications do nothing as efficiently as possible. (as in what does an application do when it has nothing to do).