<div dir="ltr"><div><div>Joe,<br><br></div>There are multiple concurrency and parallelism tools in Racket. If you want concurrency but aren't concerned about parallelism, there are software threads in Racket that will all run in the same OS thread (<a href="http://docs.racket-lang.org/reference/threads.html" target="_blank">http://docs.racket-lang.org/reference/threads.html</a>). If you want a tool that supports both concurrency and parallelism, there are places, which each run in a separate OS thread but have limited communication with each other (<a href="http://docs.racket-lang.org/reference/places.html" target="_blank">http://docs.racket-lang.org/reference/places.html</a>). What you're using, futures, are a mechanism for parallelism without concurrency -- they simulate deterministic, sequential behavior by only running in parallel as long as known-pure operations are used, which is why so many operations cause them to stop running in parallel (<a href="http://docs.racket-lang.org/reference/futures.html" target="_blank">http://docs.racket-lang.org/reference/futures.html</a>).<br>
<br></div>Racket does not currently have what many other languages do, which is a thread library that uses native OS threads with shared memory. As I understand the issue, we have avoided that primarily because it complicates the garbage collector's job, and often requires a "stop the world" approach to garbage collection. Hopefully one of the options above will suffice for your project.<br>
<div><div class="gmail_extra"><br clear="all"><div>Carl Eastlund</div>
<br><div class="gmail_quote">On Fri, Jul 26, 2013 at 12:43 AM, Joe Gilray <span dir="ltr"><<a href="mailto:jgilray@gmail.com" target="_blank">jgilray@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">Hi Robby,<div><br></div><div>Please pardon my ignorance, but is there an easy to use thread library with Racket? I've used threads in other environments and I don't recall so many restrictions.</div>
<div><br></div><div>For example, how would you do something like a %-done meter if you have very limited ability to instrument the code you are metering?</div><div><br></div><div>Thanks,</div><div>-Joe</div></div><div>
<div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Thu, Jul 25, 2013 at 5:40 PM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">hashes are definitely not future-safe, unfortunately.<span><font color="#888888"><div><br></div><div>Robby</div></font></span></div><div><div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Thu, Jul 25, 2013 at 6:50 PM, Joe Gilray <span dir="ltr"><<a href="mailto:jgilray@gmail.com" target="_blank">jgilray@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Here is an update:<div><br></div><div>I rewrote gcd and used a hash-table for the squares check. The hash-table change sped up the sequential code about 10x! Then I tried using future / touch and it seems to improve the performance a little, but there is quite a bit of blocking (on >= and hash-ref) still.<br>
</div><div><br></div><div>New code below.</div><div><br></div><div>-Joe</div><div><br></div><div><div><div><font face="courier new, monospace">; function that searches for progressive numbers for a given range of b values</font></div>
</div><div><font face="courier new, monospace">(define (find-progressive-num2 b-start b-end b-incr lim ht)</font></div><div><font face="courier new, monospace"> (define (mgcd a b) (if (= b 0) a (mgcd b (modulo a b))))</font></div>
<div>
<div><font face="courier new, monospace"> (for/sum ([b (in-range b-start b-end b-incr)])</font></div><div><font face="courier new, monospace"> (let loopa ([a (add1 b)] [suma 0])</font></div><div><font face="courier new, monospace"> (cond</font></div>
</div><div><font face="courier new, monospace"> [(> (mgcd a b) 1) (loopa (add1 a) suma)]</font></div><div><div><font face="courier new, monospace"> [(>= (* a a a b) lim) suma]</font></div><div>
<font face="courier new, monospace"> [else</font></div>
<div><font face="courier new, monospace"> (let loopc ([c 1] [sumc 0])</font></div><div><font face="courier new, monospace"> (define n (+ (* a a a c c b) (* c b b)))</font></div><div><font face="courier new, monospace"> (cond</font></div>
<div><font face="courier new, monospace"> [(>= n lim) (loopa (add1 a) (+ suma sumc))]</font></div></div><div><font face="courier new, monospace"> [(hash-has-key? ht n) (loopc (add1 c) (+ sumc n))]</font></div>
<div>
<div><font face="courier new, monospace"> [else (loopc (add1 c) sumc)]))]))))</font></div><div><font face="courier new, monospace"><br></font></div></div><div><font face="courier new, monospace">;(require future-visualizer)<br>
</font></div><div><font face="courier new, monospace">(define (euler141b)</font></div><div><font face="courier new, monospace"> (define lim 1000000000000)</font></div><div><font face="courier new, monospace"> (define ht (make-hash))</font></div>
<div><font face="courier new, monospace"> (for ([i (in-range 1 1000000)]) (hash-set! ht (sqr i) 1))</font></div><div><font face="courier new, monospace"> ; (visualize-futures</font></div><div><font face="courier new, monospace"> (let ([f1 (future (λ () (find-progressive-num2 1 1000 4 lim ht)))] </font></div>
<div><font face="courier new, monospace"> [f2 (future (λ () (find-progressive-num2 2 1000 4 lim ht)))]</font></div><div><font face="courier new, monospace"> [f3 (future (λ () (find-progressive-num2 3 1000 4 lim ht)))])</font></div>
<div><font face="courier new, monospace"> (+ (find-progressive-num2 4 1000 4 lim ht) (touch f1) (touch f2) (touch f3))))</font></div></div></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, Jul 24, 2013 at 9:46 PM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">You might try places. Writing your own gcd seems straightforward. I'm not sure about integer-sqrt?, tho. Maybe you could make a table or something if you know there are not that many numbers. <div>
<br></div>
<div>Or maybe someone will adjust the runtime to make those future safe!<span><font color="#888888"><br><div><br></div><div>Robby</div></font></span></div></div><div><div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Wed, Jul 24, 2013 at 11:34 PM, Joe Gilray <span dir="ltr"><<a href="mailto:jgilray@gmail.com" target="_blank">jgilray@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">So I should write my own (gcd ) and (square? ) functions?<div><br></div><div>I can try that, but isn't there a simple way to use threads?</div>
<div><br></div><div>Thanks,</div><div>-Joe</div><div><div>
<br></div><div><br></div></div></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jul 24, 2013 at 7:47 PM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">When I run this, the future visualizer shows that gcd and square-number? block the futures. square-number? is implemented in TR and if you take it, you find that integer-sqrt also blocks the futures. I'm not sure if those functions can be made to run safely in futures or not.<div>
<br>Robby</div></div><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div>On Wed, Jul 24, 2013 at 7:26 PM, Joe Gilray <span dir="ltr"><<a href="mailto:jgilray@gmail.com" target="_blank">jgilray@gmail.com</a>></span> wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div dir="ltr">I have a ProjectEuler problem that I wanted to speed up so I thought I would try to speed it up with future / touch.<div>
<br></div><div>I tried the following:</div><div><br></div><div><div><font face="courier new, monospace">; function that searches for progressive numbers for a given range of b values</font></div>
<div><font face="courier new, monospace">(define (find-progressive-num b-start b-end b-incr lim)</font></div><div><font face="courier new, monospace"> (for/sum ([b (in-range b-start b-end b-incr)])</font></div><div><font face="courier new, monospace"> (let loopa ([a (add1 b)] [suma 0])</font></div>
<div><font face="courier new, monospace"> (cond</font></div><div><font face="courier new, monospace"> [(> (gcd a b) 1) (loopa (add1 a) suma)]</font></div><div><font face="courier new, monospace"> [(>= (* a a a b) lim) suma]</font></div>
<div><font face="courier new, monospace"> [else</font></div><div><font face="courier new, monospace"> (let loopc ([c 1] [sumc 0])</font></div><div><font face="courier new, monospace"> (define n (+ (* a a a c c b) (* c b b)))</font></div>
<div><font face="courier new, monospace"> (cond</font></div><div><font face="courier new, monospace"> [(>= n lim) (loopa (add1 a) (+ suma sumc))]</font></div><div><font face="courier new, monospace"> [(square-number? n) (loopc (add1 c) (+ sumc n))]</font></div>
<div><font face="courier new, monospace"> [else (loopc (add1 c) sumc)]))]))))</font></div><div><br></div><div><font face="courier new, monospace">; ProjectEuler problem #141</font></div><div><font face="courier new, monospace">; n = q * d + r</font></div>
<div><font face="courier new, monospace">; q/d = d/r = a/b (where a and b are relatively prime)</font></div><div><font face="courier new, monospace">; so d = a*r/b and q = a^2 * r / b^2</font></div><div><font face="courier new, monospace">; since a and b are coprime r must be divisible by b^2 or r = c*b^2</font></div>
<div><font face="courier new, monospace">; substituting: d = a*c*b and q = a^2*c</font></div><div><font face="courier new, monospace">; n = a^3 * c^2 * b + c * b^2</font></div><div><font face="courier new, monospace">(define (euler141)<br>
</font></div><div><font face="courier new, monospace"> (define lim 10000000000)</font></div><div><font face="courier new, monospace"> (let ([f1 (future (λ () (find-progressive-num 1 1000 2 lim)))])</font></div><div><font face="courier new, monospace"> (+ (find-progressive-num 2 1000 2 lim) (touch f1))))</font></div>
</div><div><br></div><div>Unfortunately this runs no faster than the sequential version. I tried using the future-visualizer but I couldn't understand what it was telling me (I guess some operation is blocking). I also tried finer grained threads (one for each value of b), but that did no better.</div>
<div><br></div><div>Can anyone give me some pointers to successfully using future / touch?</div><div><br></div><div>Thanks,</div><div>-Joe</div></div>
<br></div></div>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div><br>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div></div></div>