From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 8CEF5BBAF for ; Thu, 28 Oct 2010 12:11:56 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai0DANfoyEzZSMDjfWdsb2JhbAChSBUBAQsLCAcRBR+/I4VIBI1b X-IronPort-AV: E=Sophos;i="4.58,250,1286143200"; d="scan'208";a="76686771" Received: from fmmailgate02.web.de ([217.72.192.227]) by mail4-smtp-sop.national.inria.fr with ESMTP; 28 Oct 2010 12:11:56 +0200 Received: from smtp08.web.de ( [172.20.5.216]) by fmmailgate02.web.de (Postfix) with ESMTP id A500617B3BE25; Thu, 28 Oct 2010 12:11:55 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localdomain) by smtp08.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #24) id 1PBPSd-0001fw-00; Thu, 28 Oct 2010 12:11:55 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.72) (envelope-from ) id 1PBPSd-0007He-5Q; Thu, 28 Oct 2010 12:11:55 +0200 From: Goswin von Brederlow To: Jeremie Dimino Cc: caml-list@inria.fr Subject: Re: [Caml-list] Asynchronous IO programming in OCaml In-Reply-To: <20101028092841.GA23531@aurora> ("Jeremie Dimino"'s message of "Thu, 28 Oct 2010 11:28:41 +0200") References: <20101025111022.GA32282@aurora> <20101025143317.GB32282@aurora> <20101025172633.GC32282@aurora> <877hh4dlog.fsf@frosties.localdomain> <20101027111835.GA5664@gaia> <877hh33g52.fsf@frosties.localdomain> <20101027153026.GD32282@aurora> <87fwvq8zec.fsf@frosties.localdomain> <20101028092841.GA23531@aurora> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) Date: Thu, 28 Oct 2010 12:11:55 +0200 Message-ID: <8762wm8w44.fsf@frosties.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1+D9m1MpoHp+Wbo7DenJEupEr7srul1jD27xQvP 9mJgyhDhxyo0+su6T4M7VoH0yg/rNHHeCZnUVkv9pDBp9mt2i8 l+oDxzHTE= X-Spam: no; 0.00; ocaml:01 0200,:01 buffered:01 buffer:01 buffer:01 simulate:01 userspace:01 lacks:01 async:01 async:01 val:01 28,:98 mfg:98 threads:01 wrote:01 Jérémie Dimino writes: > On Thu, Oct 28, 2010 at 11:00:59AM +0200, Goswin von Brederlow wrote: >> NUMA has memory dedicated to each core. Each core can access its memory >> fast. Accessing some other cores memory on the other hand is slower (and >> will have to fight for access with that core). > > And so that is a bad solution for Lwt since it runs on one system > thread. Does that matter? The copying would be going on in the kernel and use multiple cores even if the read requests all came from one core I think. >> Nah, if you can detect the error then handing is easy. The problem is >> detecting. Write() itself can fail and that is easy to detect. But >> write() succeeding doesn't mean the data has been written >> successfully. You can still get an error after that which you only get >> on fsync(). > > Take for example buffered channels, when you would have to flush the > buffer, you would launch a thread calling write and let the program > continue to write onto the channel, assuming that the write succeed. But > if one write fails, you would get the error latter. And worst, if the > program stop using the buffer after the flush, it will never get the > error. > > Jérémie True. Your program will have to handle errors. Normaly I would say that a flush/sync on a channel/file has to block the thread and continue only on error or success. Otherwise you would be talking more about barriers and simulate them with flush/sync (since userspace lacks an interface for them). Doing error handling with barriers is indeed more tricky. But I was more thinking of having async writes with error reporting. Say you have 1000 "threads" that need to write something. They all call my_write(). The my_write() function issues an async write request, blocks the "thread" and continues some other "thread". Once the write request has complete the "thread" is woken up and gets a success or failure message. "thread" here doesn't mean an actual system thread. More a logical thread like handling of a specific connection. Even more async would be to pass a callback to the my_write() that gets called on success or failure and have my_write() return directly. Again error hadnling is easy since you have the callback to handle it. So my_write would look something like this: let my_write fd off str fn = ... val my_write : Unix.file_descr Int64.t string (Unix.error option -> unit) -> unit (** Write string to file at offset and call with None on success or Some error on failure. *) The program can then decide to continue (do something else after my_write) or to block (put the rest of the code into the callback and return). MfG Goswin