evalTraversable applies one evaluation strategy to every element of a Traversable structure, producing a structure-wide strategy. With Vector's Traversable instance, it can evaluate pixel computations in parallel. section 13.4.3
Parallel pixel mapping
Use withStrategy (evalTraversable rpar) around a Vector mapping operation to create one parallel spark per element. This may generate excessive sparks and provide little or no speedup for fine-grained work. section 13.4.3
Listing 13.24 A faulty parallel mapping strategy
import Control.Parallel.Strategies as S
...
mapping :: GenericPixel px => V.Vector px -> V.Vector px
mapping pixels =
S.withStrategy (S.evalTraversable S.rpar) $ #1
flip V.imap pixels $ \i px ->
let x = i `mod` w
y = i `div` w
getPixel x' y' =
toGenericRGB <$> pixels V.!? (y' * w + x')
result = f x y getPixel $ toGenericRGB px
in fromGenericRGB result
Inspect the complete Vector mapping strategy using withStrategy and evalTraversable rpar. section 13.4.3
When evaluating a Traversable in parallel:
- Compile with threaded support and run with runtime options such as +RTS -N8 -s -RTS. section 13.4.3
- Measure spark conversion and overflow rather than assuming that element-level parallelism improves performance. section 13.4.3
