This is a multi-part message in MIME format.
--------------21EB264D4C346AB02D7B6157
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Stewart Forster wrote:
> read 0.0000094
> poll 0.0000059
> Wow! Solaris is quite a bit faster (300x) than Linux for those
> polls, and even 10 times faster for reads.
It's not fair to compare a special test program running on a idle
socket, with a live running Squid. Squid blocks in both select() and
disk read(), and both read() and recvfrom() has work to do at most
times.
Here are results from test program similar to yours, running on a idle
Pentium 133, Linux 2.0.34pre11b. [test program attached]
select 16.2610 * 10^-6 s/call
poll 22.4199 * 10^-6 s/call
read 5.6728 * 10^-6 s/call
recvfrom 6.2537 * 10^-6 s/call
accept 23.6745 * 10^-6 s/call
It seems that poll() is emulated in libc on Linux. It is slower, and I
could not find it in the kernel sources.
/Henrik
--------------21EB264D4C346AB02D7B6157
Content-Type: text/plain; charset=us-ascii; name="syscall_measure.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="syscall_measure.c"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <poll.h>
int calls; /* Call counter */
int running; /* Set to false when test ends */
void run_select(int s)
{
struct timeval timeout;
fd_set rfds;
int n;
while(++calls,running) {
/* Select test */
FD_ZERO(&rfds);
FD_SET(s,&rfds);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
n=select(16,&rfds,NULL,NULL,&timeout);
assert(n==0 || errno == EAGAIN || errno == EINTR);
}
}
void run_poll(int s)
{
struct pollfd pollfds[64];
int n;
while(++calls,running) {
/* poll test */
pollfds[0].fd=s;
pollfds[0].events = POLLIN;
n=poll(pollfds,1,0);
assert(n==0 || errno == EAGAIN || errno == EINTR);
}
}
void run_read(int s)
{
char buf[8192];
int len;
while(++calls,running) {
/* read test */
len=read(s,buf,sizeof(buf));
assert(errno == EAGAIN || errno == EINTR);
}
}
void run_recvfrom(int s)
{
char buf[8192];
struct sockaddr_in addr;
int len,alen;
while(++calls,running) {
/* recvfrom test */
alen=sizeof(addr);
len=recvfrom(s,buf,sizeof(buf), 0, &addr, &alen);
assert(errno == EAGAIN || errno == EINTR);
}
}
void run_accept(int tcp)
{
struct sockaddr_in addr;
int s,alen;
while(++calls,running) {
/* accept test */
alen=sizeof(addr);
s=accept(tcp, &addr, &alen);
assert(errno == EAGAIN || errno == EINTR);
}
}
void end_test(int sig)
{
running=0;
}
void do_test(int s, char *test, void (*test_func)(int))
{
/* printf("Running %s\n",test); */
running=1;
calls=0;
sleep(1); /* Syncronise with the clock */
signal(SIGALRM,end_test);
alarm(10);
test_func(s);
printf("%-10s %8.4f * 10^-6 s/call\n", test, 10.0e+6 / calls );
}
int main(int argc, char **argv)
{
int tcp,udp;
int i;
struct sockaddr_in addr;
tcp=socket(AF_INET,SOCK_STREAM,0);
udp=socket(AF_INET,SOCK_DGRAM,0);
memset(&addr,0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(40000);
bind(tcp, (struct sockaddr *)&addr, sizeof(addr));
bind(udp, (struct sockaddr *)&addr, sizeof(addr));
fcntl(tcp, F_SETFL, fcntl(tcp, F_GETFL, 0) | O_NONBLOCK);
fcntl(udp, F_SETFL, fcntl(udp, F_GETFL, 0) | O_NONBLOCK);
setsockopt(tcp,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
setsockopt(udp,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
listen(tcp,64);
for(i=0;i<10;i++) {
do_test(udp,"select",run_select);
do_test(udp,"poll",run_poll);
do_test(udp,"read",run_read);
do_test(udp,"recvfrom",run_recvfrom);
do_test(tcp,"accept",run_accept);
}
close(tcp);
close(udp);
exit(0);
/* NOT REACHED */
}
--------------21EB264D4C346AB02D7B6157--
Received on Tue Jul 29 2003 - 13:15:50 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:11:48 MST