HP-UX TCP/IP Performance White Paper, March 2008

28
/dev/poll driver and registers a set of file descriptors that it wants to monitor along with the set of events
it wants to monitor for those file descriptors. Then it can issue an DP_POLL ioctl() call on the event port
driver to check which events have occurred on the registered file descriptors. The DP_POLL ioctl() on
return specifies the file descriptors (if any) that have events pending and which events have occurred.
/dev/poll usually performs better than select() and poll() when the application has registered a
very large number of file descriptors that have specified events occurring sparsely. However, in cases
where specified events are likely to occur simultaneously on a large number of registered file descriptors,
performance gain may be diminished. Also, /dev/poll is better suited for applications that do not open
and close the polled file descriptors very often as the cost of registering the polled file descriptors may
become more than the gain achieved from polling them.
See poll(7) for more details on event port mechanism and the /dev/poll interface.
5.3 send() and recv() Socket Buffers
When writing applications that transmit or receive large quantities of data, it may be important to consider
the values of socket parameters often referred to as the "socket buffer sizes", namely the SO_SNDBUF and
SO_RCVBUF socket options. These options can be set and examined using the setsockopt() and
getsockopt() system calls.
The precise effect of these parameters varies between implementations of the socket API, and between types
of socket. The behavior for SOCK_DGRAM is fairly standard, and is not discussed here.
For SOCK_STREAM, there are some aspects of the behavior which are not clearly delineated in the UNIX
03 or other interface specifications, and so precise behavior varies between implementations. The
following discussion describes the behavior which is specific to HP-UX 11i.
5.3.1 Data Buffering in Sockets
The basic idea of the SO_RCVBUF and SO_SNDBUF socket options is to allow the application to regulate
the amount of data that can be buffered in the pipeline between the sending side and the receiving side.
The relationship between the values of these parameters and the amount of data in the pipeline is
somewhat imprecise, as discussed below.
For a TCP (SOCK_STREAM) socket, there are essentially 3 places data can be buffered:
a) Data produced by an application and buffered before reaching the sending protocol code.
b) Data "in flight" between the sender and receiver (including packets on the sending side which have
been queued by the protocol code but not yet sent, and packets on the receiving side which have
been received but not yet processed by the protocol code).
c) Data buffered by the receiver after protocol processing, waiting to be consumed by an application.
It is often the case that application programmers may make assumptions about the relationship between the
values of the SO_SNDBUF or SO_RCVBUF parameters and the amount of data buffered at some or all of the
places in the pipeline mentioned above.
5.3.2 Controlling Socket Buffer Limits
If an application sets the value of the SO_RCVBUF parameter before establishing a connection, TCP will use
the value of SO_RCVBUF when negotiating the TCP receive window. If the value is large, then a window
scaling option value may be negotiated. The receive window size of the peer, in combination with the
SO_SNDBUF set by a sending application and TCP congestion control algorithms, limit the total amount of
data that can be buffered in a single direction over a given connection.