From owner-freebsd-hackers Sun Jun 17 14:38:58 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from earth.backplane.com (earth-nat-cw.backplane.com [208.161.114.67]) by hub.freebsd.org (Postfix) with ESMTP id 2C63C37B407 for ; Sun, 17 Jun 2001 14:38:44 -0700 (PDT) (envelope-from dillon@earth.backplane.com) Received: (from dillon@localhost) by earth.backplane.com (8.11.3/8.11.2) id f5HLcaS08280; Sun, 17 Jun 2001 14:38:36 -0700 (PDT) (envelope-from dillon) Date: Sun, 17 Jun 2001 14:38:36 -0700 (PDT) From: Matt Dillon Message-Id: <200106172138.f5HLcaS08280@earth.backplane.com> To: Jonathan Lemon Cc: sascha@schumann.cx, hackers@FreeBSD.ORG Subject: Re: poll(2)'s arbitrary limit References: <200106172033.f5HKXEn56198@prism.flugsvamp.com> Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG :Well, I have to disagree, as the conclusion in the above paper is :misleading. Basically, they say that if a listen socket returned :by select() becomes ready, then it is more efficient to call accept() :on the socket multiple times, rather than once per select() call. : :Well gee, that's nice, and quite true, but has nothing to do with :the efficiency (or lack thereof) of select() itself. This is simply :the old 'polling' vs 'interrupt' argument that has been around for :ages (see also: 'interrupt livelock'). :-- :Jonathan Well, not quite... select() isn't quite as bad as it appears. Consider the case of a heavily loaded web server which is select()ing on 500 descriptors. If the select() returns 20 ready descriptors and the web server then proceeds to process those descriptors by the time it gets around to calling select() again it is likely that another 20 descriptors will be ready. So rather then having O(N^2) overhead, select() winds up with O(25N) overhead (500/20 = 25), which isn't all that bad. The actual overhead of making the select() call relative to doing other work winds up going *DOWN* under heavier loads and *UP* in lighter loads. Where select() breaks down is when you have hundreds of descriptors but the load is not high enough to cause more then a few to be 'ready' at any given moment. The select() based program will still be reasonably responsive, but it will wind up eating a considerably greater amount of cpu to get that responsiveness. Something like kqueue() has low cpu overhead and high efficiency under all load conditions, select() has high overhead under lightly loaded conditions and while it gets much better with load, it still will be nowhere near as good as kqueue(). But that doesn't necessarily mean that a select() based loop will become unmanageable! And when you get into the thousands of descriptors, then select's scanning overhead can really take its toll. An argument can also be made for the increased efficiency you get with batch processing. Take the web server example again, this time focusing an the listen descriptor. From the point of view of efficiency, allowing a number of new connections to build up on the listen socket and then accept()ing them in a tight loop is in fact more cpu-efficient then waking up the process for each one. You get this effect under heavier loads whether you are using select(), poll(), or kqueue(). -Matt To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message