From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 29EA4BCAC for ; Wed, 25 May 2005 03:42:23 +0200 (CEST) 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 j4P1gMUY011478 for ; Wed, 25 May 2005 03:42:22 +0200 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 DAA15533 for ; Wed, 25 May 2005 03:42:22 +0200 (MET DST) Received: from wproxy.gmail.com (wproxy.gmail.com [64.233.184.203]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id j4P1gLOv011474 for ; Wed, 25 May 2005 03:42:21 +0200 Received: by wproxy.gmail.com with SMTP id 69so434912wri for ; Tue, 24 May 2005 18:42:21 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=YatdX+WabQMk3pPOheOBLDNLQh4Q4HLpMhqgjhgL6Vo46h68ZhQ4qIjpiN9F0Zuj9PqJolFJ33DGm79wLVYGaWjBqTNCZuPyyNXz/o0fuR8X/eaV2tDRSg/xE16eNdZEHrm94e2xRT/l0YUUuNW2255J4mP2d681QwrHjj9Bn6w= Received: by 10.54.8.8 with SMTP id 8mr906334wrh; Tue, 24 May 2005 18:42:21 -0700 (PDT) Received: by 10.54.2.21 with HTTP; Tue, 24 May 2005 18:42:21 -0700 (PDT) Message-ID: <891bd339050524184221de71b8@mail.gmail.com> Date: Tue, 24 May 2005 21:42:21 -0400 From: Yaron Minsky Reply-To: yminsky@cs.cornell.edu To: Caml Mailing List Subject: Re: Efficient I/O with threads In-Reply-To: <891bd33905052415145bb1818f@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <891bd33905052415145bb1818f@mail.gmail.com> X-Miltered: at nez-perce with ID 4293D7FE.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at nez-perce with ID 4293D7FD.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; yaron:01 minsky:01 yminsky:01 threads:01 buffering:01 ocaml:01 buffering:01 reimplement:01 buffer:01 ocaml:01 yaron:01 minsky:01 yminsky:01 outputting:01 sexp:01 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_BY_IP autolearn=disabled version=3.0.2 X-Spam-Level: An addendum. One thing that was pointed out to me in some private emails was that buffering could solve the problem on the reading side as well. That is true, as far as it goes --- that's why I said that I can't think of a _clean_ way of handling it. One of the nice things about ocaml IO channels is that they handle buffering, and it seems a shame to have to reimplement buffering on top of them. Put another way, the problem with input/output channels appears to be that the buffering is done on the wrong side of the lock. You shouldn't have to do any locking to do IO when the request can be satisfied from the buffer. The fact that IO channels always require you to acquire the lock means that the performance is crappy unless you bundle up writes by yourself. Fixing this is perhaps too deep of a change to drive into the OCaml system at this point. Is this a problem that is addressed by the I/O channels provided by any other library such as extlib? Yaron On 5/24/05, Yaron Minsky wrote: > We've been running into some interesting problems building highly > efficient I/O routines in threaded code in ocaml, and I'm curious if > anyone else has some thoughts on this. The basic problem seems to be > that the locking and unlocking of the IO channels seems to take a > large fraction of the execution time. >=20 > A little bit of background first. The data type we're outputting is > basically a simple s-expression, with the following type: >=20 > type sexp =3D Atom of string | List of sexp list >=20 > We write out an s-expression by writing a tag-byte to determine > whether the s-expression is an atom or a string. If the s-expression > is an atom, we then write a 4-byte int, which is the length of the > string, and then the string. If the s-expression is a list, we write > an atom which is the number of s-expression that are contained, and > then write those s-expressions. >=20 > It's very easy to write parsing and marshalling for this type of wire > protocol, but that code turns out to be quite inefficient, because you > end up making too many calls to the input and output functions, and > each one of those calls requires releasing and acquiring locks. I > just can't think of a clean way of implementing a reader for this kind > of protocol. (a writer could be done by writing stuff to a buffer > first, and then writing the whole buffer out at the socket at once.) >=20 > Any thoughts? > Yaron >