From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Zelphir Kaltstahl Newsgroups: gmane.lisp.guile.user Subject: Re: Guile fibers return values Date: Mon, 6 Jan 2020 23:45:10 +0100 Message-ID: References: <20200105123329.5019662bdf1895a4164faf62@gmail.com> <20200105142358.4ad96d15a23a0b947b2d55e3@gmail.com> <547672e4-30f7-2783-f3d5-199417a71c98@posteo.de> <20200105214555.60e424b8cf86456e188c75f6@gmail.com> <7661b27f-787e-fc8f-d653-5fbabffa01f7@posteo.de> <20200106211456.68c8a637631a4e1e977d8443@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="230164"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Icedove/52.9.1 Cc: Guile User To: John Cowan , Chris Vine Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Mon Jan 06 23:46:27 2020 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iob8j-000xj1-Lb for guile-user@m.gmane.org; Mon, 06 Jan 2020 23:46:25 +0100 Original-Received: from localhost ([::1]:44904 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iob8h-0008CU-RC for guile-user@m.gmane.org; Mon, 06 Jan 2020 17:46:23 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:40184) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iob7e-00085l-3J for guile-user@gnu.org; Mon, 06 Jan 2020 17:45:20 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iob7c-0006MG-3b for guile-user@gnu.org; Mon, 06 Jan 2020 17:45:17 -0500 Original-Received: from mout01.posteo.de ([185.67.36.65]:58167) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iob7b-0006KB-FY for guile-user@gnu.org; Mon, 06 Jan 2020 17:45:16 -0500 Original-Received: from submission (posteo.de [89.146.220.130]) by mout01.posteo.de (Postfix) with ESMTPS id 96E6516005F for ; Mon, 6 Jan 2020 23:45:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017; t=1578350713; bh=jB0jN1nlHTXVG5nnjHQBihqHcNRPJpRuJPXM7pSkuAE=; h=Subject:To:Cc:From:Date:From; b=fZNHJyMZ/RIy826+tT9M7PHj0+aGUyPD5ZyphgargQUaJWI0MucTnNHaRU1t65S3m nwxeUbzrvnN641SvymE65C+sdb0c0NtOYDso1oB/9coj4SxFzjc9+NIBDKP7I6Y3/Y Wd1eNn/1TIE0BgiP7Ile4V6FEs0AK7+WiIg1jyMQ5AC8mzpCU7PRqjMsU3FcjsUiMj lwYOf+pApzQc74MQdhlf/rZPbDptIeUVTJBcQGjyoKgBEB+8V7I2DYhleE2toLv/LG 27v+vifyT39R+J3Q5L116yVK1G5+qjeOvV0NC9gCJ+K06LgiP/3EohDLje5oSzNOvd jEdvafNxu9zeg== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 47s9ZJ4gxLz6tm6; Mon, 6 Jan 2020 23:45:12 +0100 (CET) In-Reply-To: Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 185.67.36.65 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:16002 Archived-At: Hello John! Thanks for your reply! On 06.01.2020 22:47, John Cowan wrote: > Conceptually, parallelism and concurrency are two different and partly > independent things.=C2=A0 Parallelism refers to physically simultaneous > execution, as when you throw a ball into the air in each hand and > catch it in the same hand.=C2=A0 Each throw-catch cycle is a parallel > process (using "process" in the broad sense of the term).=C2=A0 > Concurrency, on the other hand, is *logically* simultaneous execution, > as when you juggle three balls in one or two hands.=C2=A0 Now the > throw-catch cycle of each ball from one hand to the other is a > concurrent process, and it is also a parallel process if you use two > hands.=C2=A0 If you are using one hand, however, there is no parallelis= m in > juggling. Yes, that is pretty clear. Parallelism and concurrency are not the same, I know that. One could also say, that one can have concurrent execution on a single core, even multiple processes, but cannot have parallel execution on that single core. With concurrency, even on one core, one needs to look out for many things like concurrent updates or mutating state, as one, in the general case, does not know when one process will be running and when the other. > To make matters more confusing, "futures" in Racket are for > parallelism, whereas in Guile they are for concurrency.=C2=A0 Guile > "parallel" and friends are executed on futures (which are executed on > OS threads), but use at most as many futures as there are CPUs, so > physically simultaneous execution is at least encouraged if not > actually guaranteed. I think that is a typo maybe? The futures guide says: "The (ice-9 futures) module provides futures, a construct for fine-grain parallelism." Otherwise that would indeed be very confusing. Or do you say this, because on a single core machine, there would be no parallelism and thus one cannot say, that Guile's futures will enable parallelism in general, but can say, that they in general enable concurrency? > Racket parallelism only operates until one of the parallel processes > blocks or needs to synchronize (which includes things like allocating > memory): they are not implemented on top of Racket threads, which are > for concurrency (and have nothing to do with OS threads).=C2=A0 Yes, as far as I understand, Racket threads are so called "green threads" (like in Python). To use multiple cores in the general case, one needs to make use of Racket's "places" instead, which are additional Racket VMs running. > A Scheme promise can be viewed as a type of parallel process that > doesn't actually provide parallelism (and in fact my parallel pre-SRFI > is called "parallel promises" and treats=C2=A0ordinary promises as a > degenerate case) or as a future that doesn't start to execute until > you wait for it to finish (and my futures pre-SRFI also treats > promises as a degenerate case). I think of "promises" as something that enables asynchronous execution. Don't beat me for this: "Just like in JavaScript" basically :D I don't know, if that notion is wrong in the Scheme context though. So far I found the following approaches to do things in parallel in GNU Guile: 1. futures 2. parallel forms (built on futures, probably "just" convenience) 3. fibers library I have not considered to look for "promises" yet, as I did not think them to be a parallelism construct or concept. However, you are mentioning them. Does that mean, that I should look into them as well or is it rather a general explanation to get the concepts cleanly separated? It seems not like they could parallelize any algorithm. At least not, if they share the character of JavaScript promises. And hello Chris! I have just checked, whether futures run in parallel for the example of the Racket docs and they seem to run in parallel, although the CPU is not 100% busy, probably because of other factors, like allocations: --------8<--------8<-------- (use-modules (ice-9 futures) ;; SRFI 19 for time related procedures (srfi srfi-19)) ;; Just defining a timing macro here to conveniently measure elapsed time= of ;; evaluating expressions. (define-syntax time (syntax-rules () [(time expr expr* ...) (begin (define start-time (current-time time-monotonic)) expr expr* ... (define end-time (current-time time-monotonic)) (let* ([diff (time-difference end-time start-time)] [elapsed-ns (+ (/ (time-nanosecond diff) 1e9) (time-second diff))]) (display (format #t "~fs~%" elapsed-ns))))])) (define (mandelbrot iterations x y n) (let ([ci (- (/ (* 2.0 y) n) 1.0)] [cr (- (/ (* 2.0 x) n) 1.5)]) (let loop ([i 0] [zr 0.0] [zi 0.0]) (if (> i iterations) i (let ([zrq (* zr zr)] [ziq (* zi zi)]) (cond [(> (+ zrq ziq) 4.0) i] [else (loop (+ i 1) (+ (- zrq ziq) cr) (+ (* 2.0 zr zi) ci))])))))) (time (let ([f (future (lambda () (mandelbrot 10000000 62 501 1000)))]) (list (mandelbrot 10000000 62 500 1000) (touch f)))) (time (mandelbrot 10000000 62 501 1000)) --------8<--------8<-------- On my machine both timed expressions run in approximately the same time, which I conclude from, that 2 cores were used and the work was done in parallel. Regards, Zelphir