From: Lev W. <vl...@ne...> - 2001-12-26 20:15:57
|
Wesley W. Terpstra wrote: > On Tue, Dec 25, 2001 at 02:50:46PM -0800, Lev Walkin wrote: > >>>MD_USE_SYSV/BSD_ANON_MMAP: >>> Idea 1: >>>#ifdef MAP_ANON >>>do BSD stuff >>>#els >>>do SYSV stuff >>>#endif >>> >>> Idea 2: >>>always open /dev/zero >>>#ifdef MAP_ANON >>>flags |= MAP_ANON; >>>#endif >>>mmap >>> >>It is a bad idea to invoke useless open() call with mmap(), if we >>can avoid it. >> > > Ok, that doesn't rule out idea 1 though. Does MAP_ANON being defined > guarantee it is available and works? I think, yes. > Alternately, if build system == host system: run a check for sysv/bsd > semantics. If cross compiling fall back to idea 2 or malloc. (whichever is > better) make a ./configure --able parameter. > Again, what's wrong with malloc? I thought it uses mmap for large > allocations internally? In GNU libc - yes, it does. In other systems - generally NO. >>>MD_ACCEPT_NB_INHERITED: >>> >>> Why not just assume it's not inherited and always reset the thing >>>nonblocking? Is it really such a performance hit? >>> >>System call is always a performance hit. But related with other >>types of activities during thread initialization, it is almost nothing. >> > > Ok, > > io.c: > static int st_nb_inherited = -1; > > void st_determine_if_nb_inherit(int fd) > { > long flags = fcntl(fd, F_GETFL); > if ((flags & O_NONBLOCK) != 0) > st_nb_inherited = 1; > else > st_nb_inherited = 0; > } > > ... > // code using #ifdef now: > if (st_nb_inherited == -1) st_derermine_if_nb_inherit(sock); > if (st_nb_inherited) _st_newfd_new(sock, 0, 1); > else _st_newfd_new(sock, 1, 1); > ... > EOF > > This should address the performance issue...? How ugly... But OK. >>>MD_ALWAYS_UNSERIALIZED_ACCEPT: >>> >>> I don't know enough about this to write a test. Could someone give >>>me a hand? >>> >>Actually, it is somewhat hard to write a multiprocess test of such >>a nature within automake framework. You should consider using internal >>__OS_Type__ variables in header or code files to protect this place. >> > > Hrm. Ok then, which OSs need serialized accept? Original md.h has the description of it. > One last thing: I have it using poll() whenever the function is available > since I am under the belief that poll() is faster than select() - is this > wrong? Well. This is a good question. Generally, neither is faster. If you have 10 active file descriptors to handle, poll() will be better, because it transfers only 80 bytes to kernel. If you have 50 active descriptors, select() will do better because it will transfer to kernel only 384 bytes (instead of poll()'s 400). But you will be not able to supply more than 1024 descriptors to select() without recompiling kernel on most systems. Another bad thing is that Linux kernel internally goes FOUR TIMES through the array supplied by poll(), so, it will perform better than select() only with relatively small number of descriptors. In other hand, as I've said, poll() can handle more than 1024 file descriptors in a convenient way. Actually, it is the best thing in the ST library to optimize. Neither poll() nor select() will give the desirable performance on typical server systems, because of large overhead. Suppose, you have 2000 clients with only 10 residing on the fast connections. It is clear, that poll() or select() will scan the whole table only to determine that the same small set of descriptors is active. It will require a completely another approach to overcome this table scans on every call to poll() or select(). This approach is to report the user process the CHANGE in file descriptors state. I encourage you to look at kqueue()/kevent() calls on FreeBSD, the /dev/poll mechanism on Solaris, /dev/poll and /dev/epoll on modern Linux systems. -- Lev Walkin vl...@ne... |