Re: [Haskell-cafe] Can't seem to get `par` working appropriately with lists

2008-02-22 Thread Luke Andrew

Felipe Lessa wrote:

On Thu, Feb 21, 2008 at 8:58 AM, Luke Andrew [EMAIL PROTECTED] wrote:
  

 test2.hs:

import Control.Parallel

fib1 n = if n == 0 then 0 else if n == 1 then 1 else fib1 (n-1) +
 fib1 (n-2)
fib2 n = if n == 0 then 0 else if n == 1 then 1 else fib2 (n-1) +
 fib2 (n-2)
fiblist1 n = [fib1 x| x - [1..n]]
fiblist2 n = [fib2 x| x - [1..n]]

main = do print $ zipWith (+) (fiblist2 37 `par` fiblist1 37)
 (fiblist2 37)



Besides what Jules Bean said, note also that 'par' works a bit like
'seq', only evaluating until WHNF. So even if you said

main =
  let f1 = fiblist1 37
  f2 = fiblist2 37
  in print $ zipWith (+) (f2 `par` f1) f2

you still wouldn't get what you want. Why? It only evaluates f1 and f2
until it reaches [] or (_:_), and nothing more, it doesn't even try to
figure out that f2 is _:_:_:_:···:[] nor it tries to see that f2 is
1:_, but you wanted that the parallel computation went until f2 was
1:1:2:3:···:[].

To do that, force the list (i.e. do a deep seq). There's
Control.Parallel.Strategies to help you doing this, but if you want to
reimplement it, try

force []  = ()
force (x:xs) = x `seq` force xs

main =
  let f1 = fiblist1 37
  f2 = fiblist2 37
  in print $ zipWith (+) (force f2 `par` f1) f2

'par' will try to see that 'force f2' is really (), but to do that
'force' will go all the way down thru the list forcing its spine and
its values.

HTH,

  
Thanks Felipe, works as advertised. Guest I'm going to have to read up 
on WHNF, I just ignored it after my initial success  hoped it would 
continue to work. Guess I should have RTFM :)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Can't seem to get `par` working appropriately with lists

2008-02-21 Thread Luke Andrew

Hopefully an easy one here; after reading Don Stewart's blog posts about
parallel Haskell and with a shiny new quad-core cpu begging for a
workout, i thought I'd give Haskell a try. I've also been meaning to
write a ray-tracer, so I started with that. I've got the initial
ray-tracer working, and am now looking to parallize it. I tried using
the `par` function to evaluate things in parallel, but I couldn't get it
to work with lists. I simplified my problem down into the following 2
test cases:

(there are two fibonacci functions to ensure haskell treats them as 2
independent computations to be spread across 2 cores)

test1.hs:

   import Control.Parallel

   fib1 n = if n == 0 then 0 else if n == 1 then 1 else fib1 (n-1) +
fib1 (n-2)
   fib2 n = if n == 0 then 0 else if n == 1 then 1 else fib2 (n-1) +
fib2 (n-2)

   main = do print $ (fib2 37 `par` fib1 37) + (fib2 37)

compilation  testing:

   [EMAIL PROTECTED]:~/mcls$ ghc -O2 -threaded --make test1
   [1 of 1] Compiling Main ( test1.hs, test1.o )
   Linking test1 ...

   [EMAIL PROTECTED]:~/mcls$ time ./test1 +RTS -N1
   48315634

   real0m5.856s
   user0m5.816s
   sys 0m0.004s

   [EMAIL PROTECTED]:~/mcls$ time ./test1 +RTS -N2
   48315634

   real0m3.450s
   user0m6.734s
   sys 0m0.024s

As expected, running it with 2 cores is substantially faster. Doing
almost the same thing, but with lists, doesn't seem to have any
significant speed difference:

test2.hs:

   import Control.Parallel

   fib1 n = if n == 0 then 0 else if n == 1 then 1 else fib1 (n-1) +
fib1 (n-2)
   fib2 n = if n == 0 then 0 else if n == 1 then 1 else fib2 (n-1) +
fib2 (n-2)
   fiblist1 n = [fib1 x| x - [1..n]]
   fiblist2 n = [fib2 x| x - [1..n]]

   main = do print $ zipWith (+) (fiblist2 37 `par` fiblist1 37)
(fiblist2 37)

compilation  testing:

   [EMAIL PROTECTED]:~/mcls$ ghc -O2 -threaded --make test2

   [EMAIL PROTECTED]:~/mcls$ time ./test2 +RTS -N1
   [2,2,4,6,10,16,26,42......405774,18454930,29860704,48315634]

   real0m15.294s
   user0m15.196s
   sys 0m0.013s

   [EMAIL PROTECTED]:~/mcls$ time ./test2 +RTS -N2
   [2,2,4,6,10,16,26,42......405774,18454930,29860704,48315634]

   real0m15.268s
   user0m15.169s
   sys 0m0.013s

I've tried using bang patterns in various places, but to no avail. Any
ideas?

Luke Andrew.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe