Re: Re: [Haskell-cafe] Re: A problem with par and modules boundaries...

On Sat, 2009-05-23 at 13:31 -0400, Mario Blažević wrote:
You could probably see exactly what's happening in more detail by going through the Core output.
Thank you, this advice helped. The Core output indicates that function `test' evaluates the arguments to `parallelize' before it calls it. In other words, the call to `parallelize' is optimized as a strict function call -- which it is. The problem is that this optimization evaluates the arguments sequentially. Compiling with optimizations turned off regains the parallel execution.
I guess I will report this as a GHC bug. Or is it a feature request?
As Duncan suggessted, try with GHC head (grab a snapshot). `par` et al are much improved.
I already have, with the snapshot from 21st of April. It behaves the same as 6.8.2, except it runs for twice as long.
I'd like to take back a part of what I said before, though: `parallelize' should be strict only in its second argument.
parallelize a b = a `par` (b `pseq` (a, b)) GHC infers that strictness of parallelize. It thinks that it is lazy in both args (you can check this yourself using ghc --show-iface). That's because the definitions of par and pseq use the function 'lazy': -- The reason for the strange "lazy" call is that it fools -- the compiler into thinking that pseq and par are non-strict in -- their second argument (even if it inlines pseq at the call site). -- If it thinks pseq is strict in "y", then it often evaluates -- "y" before "x", which is totally wrong. pseq x y = x `seq` lazy y par x y = case (par# x) of { _ -> lazy y } So GHC thinks that par is lazy in both arguments, while it thinks pseq is strict in the first and lazy in the second.
Its strictness in the first argument should be the same as with `par`.
Yes, which it is.
Even though `parallelize x y' always evaluates both x and y,
Be careful about what you mean. Yes, it starts the evaluation of x in parallel with y, but that does not mean it is strict in x, as you notice with your example of undefined below.
the following test works fine with optimizations even if `parallelize' is imported:
main = putStrLn (snd $ parallelize undefined "Hello, World!")
So the function is not strict, and I don't understand why GHC should evaluate the arguments before the call.
Right, it's lazy in the first and strict in the second argument. As far as I can see we have no evidence that is is evaluating anything before the call.
Does anybody know of a pragma or another way to make a function *non-strict* even if it does always evaluate its argument? In other words, is there a way to selectively disable the strictness optimization?
Yes, which is what pseq and par already do. If there's a bug, we need to reproduce it and report it. I cannot reproduce it. Duncan
participants (1)
-
Duncan Coutts