Ticket #5234 (closed bug: worksforme)

Opened 2 years ago

Last modified 18 months ago

The parListWHNF optimisation isn't

Reported by: duncan Owned by: simonmar
Priority: high Milestone: 7.4.1
Component: libraries (other) Version: 7.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description

In Control.Parallel.Strategies there is:

parListWHNF :: Strategy [a]
parListWHNF xs = go xs `pseq` return xs
  where -- go :: [a] -> [a]
           go []     = []
           go (y:ys) = y `par` go ys

Plus a rule:

{-# RULES 
 "parList/rseq" parList rseq = parListWHNF
 #-}

However this rule never fires because both parList and rseq get inlined too early (they have no INLINE [n] pragma).

This makes a difference because parListWHNF really is better than parList rseq. Consider this trivial test program:

main =
  let xs = [0..100000] `using` parListWHNF
   in print (sum xs)

This correctly generates 100001 dud sparks. They are all dud because all the elements of [0..100000] are already evaluated.

However if we use the same program with parList rseq then we get 100001 converted (but obviously rather trivial) sparks. This is less good (it runs at half the speed) because it pushes all these sparks through the spark pool, rather than not bothering to put them in the spark pool in the first place.

Change History

Changed 2 years ago by duncan

I've not checked, but I'd be very suspicious of the RULE for evalBufferWHNF too. I bet it never fires, again because the things it matches on have nothing to prevent them from being inlined too early.

Changed 2 years ago by simonpj

  • owner set to simonmar
  • priority changed from normal to high
  • milestone set to 7.2.1

Simon, you know what's going on here. Shouldn't be hard to fix.

Simon

Changed 21 months ago by igloo

  • milestone changed from 7.2.1 to 7.4.1

Changed 20 months ago by simonmar

  • status changed from new to closed
  • resolution set to worksforme

Seems to work with 7.0.3, 7.2.1, and with HEAD:

$ ghc-7.2.1 -ddump-rule-firings -O2 parlist.hs -threaded -fforce-recomp -rtsopts      
[1 of 1] Compiling Main             ( parlist.hs, parlist.o )
Rule fired: Class op enumFromTo
Rule fired: parList/rseq
Rule fired: SPEC Data.List.sum
Rule fired: Class op show
Rule fired: enumDeltaToInteger
Rule fired: >=#
Linking parlist ...

I've checked that we get the dud sparks as required, and the parBuffer rule also works.

Changed 18 months ago by duncan

Note that it is still not robust to abstraction without the INLINE pragma. I think I've hear Roman say before that GHC should just warn if any name mentioned on the LHS of a rule does not have an INLINE [x] pragma.

Note: See TracTickets for help on using tickets.