From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id 34514BBA7 for ; Tue, 7 Feb 2006 20:44:46 +0100 (CET) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k17JijE7029344 for ; Tue, 7 Feb 2006 20:44:45 +0100 Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id UAA18232 for ; Tue, 7 Feb 2006 20:44:44 +0100 (MET) Received: from ciao.gmane.org (main.gmane.org [80.91.229.2]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k17Jihlt029335 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 7 Feb 2006 20:44:44 +0100 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1F6YlJ-00056C-Mb for caml-list@inria.fr; Tue, 07 Feb 2006 20:44:29 +0100 Received: from 0x535f962a.boanxx20.adsl-dhcp.tele.dk ([83.95.150.42]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 07 Feb 2006 20:44:29 +0100 Received: from spam by 0x535f962a.boanxx20.adsl-dhcp.tele.dk with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 07 Feb 2006 20:44:29 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: caml-list@inria.fr From: Bardur Arantsson Subject: Re: async networking Date: Tue, 07 Feb 2006 20:43:57 +0100 Message-ID: References: <1139129530.15565.3.camel@localhost.localdomain> <1139160736.10812.3.camel@localhost.localdomain> <1139288125.19213.36.camel@rosella> <1139338868.12287.185.camel@localhost.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: 0x535f962a.boanxx20.adsl-dhcp.tele.dk User-Agent: Mail/News 1.5 (X11/20060112) In-Reply-To: <1139338868.12287.185.camel@localhost.localdomain> Sender: news X-Miltered: at nez-perce with ID 43E8F8AD.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at nez-perce with ID 43E8F8AB.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; async:01 gerd:01 stolpmann:01 argg:01 labltk:01 lablgtk:01 lablgtk:01 descriptors:01 descriptors:01 sockets:01 invocation:01 ocaml:01 allocations:01 latency:01 latency:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.3 Gerd Stolpmann wrote: > Am Dienstag, den 07.02.2006, 18:44 +0100 schrieb Bardur Arantsson: >> skaller wrote: >>> On Mon, 2006-02-06 at 19:34 +0100, Bardur Arantsson wrote: >>> >>>> However, if you want very high-performance networking >>>> you'd be better off with something closer to the metal, i.e. something >>>> like a libevent wrapper >>> Argg no. Libevent isn't a library, it doesn't control invert. >>> It is a monolithic framework. Therefore it is not very useful because >>> your code will no longer be composable. In particular, >>> there is no way to compose two such frameworks, for example >>> you cannot use it with an event driven GUI framework. >>> >> Note that I said 'high-performance'. >> >> Point #1: select() and anything based on it (I believe Equeue still is >> though I haven't looked at it for quite a while) is woefully inadequate >> for high performance I/O except in very specific circumstances. > > Yes, the default Equeue implementation bases simply on select(). It is, > however, possible to develop alternate implementations. Currently, there > are three of them which integrate into the event loops of labltk, > lablgtk1 and lablgtk2. One could, for example, easily add an > implementation for advanced kernel interfaces like epoll. Actually, it might be quite interesting to see one based on poll()/epoll(), but I suspect it wouldn't matter much compared to all the other stuff that's going in the Equeue code. This is just a very vague hunch, though. [--snip--] > > select() is, as far as I know, only bad if the file descriptors are > linked with many different processes, because all that processes must be > waked up in order to check the descriptors (even if no I/O can happen). > But if you only have Internet sockets, I expect that select() performs > well. There are lots of problems with select(). For example, it generally requires copying the file descriptor sets from user-space to kernel space for every select() invocation, the scanning of active file descriptors afterward can be inefficient(*), from OCaml it also causes more pressure on the GC through list allocations for result sets, etc. etc. (*) If your file descriptor set has large "holes" -- which can develop if clients have very variable connection lifetimes -- you'll end up scanning lots of memory you don't really need to scan. Algorithmically it's all still O(n), but the constants can be _very_ different. > >> Point #2: It is not customary for UI applications to require >> particularly high-performance I/O, thus rendering the non-composability >> issue moot. > > There are many aspects of high performance, for example throughput, > latency, and whether a low or high number of descriptors are watched. Sure. It's just that select() sucks performance-wise for most purposes. The alternatives like the OpenBSD kqueue and poll() are usually much better. > UI applications are often interested in low latency for a moderate number > of descriptors. Sure, but not at the level I'm talking. I'm talking about saturating high-bandwidth links, ultra-low latency -- though usually not at the same time, obviously ;). You know, the kind of stuff you might even consider using C/C++ (shudder) for just to avoid GC. > > I think there is another point why it is a bad idea to distinguish > between, say UI and server applications. Network components should be > shareable between all types of applications. Yup. Though all non-blocking I/O has the basic problem of "one event loop to rule them all" unless you go with several threads, each running their own event loop... At which point you might as well have each of those components just using regular blocking I/O and using threads as appropriate. Note, I'm not talking about performance characteristics here, just design. Also, exception handling and such can be handled much more nicely with a threaded design since they don't "invert" the control logic the same way non-blocking I/O tends to do. > For example, an HTTP component is useful for both, so why should we develop an extra one for > specific needs of high performance? > Sometimes you just need that last bit of performance where a "nice" implementation just won't do. Cheers, -- Bardur Arantsson [Postmodernism] is more like a three year old throwing his blocks around the room because he got frustrated with his failed attempts to stack them higher. Black Parrot @ http://slashdot.org