2010-06-27 11:12:52 +04:00
speculation
===========
2010-06-28 02:34:37 +04:00
A framework for safe, programmable, speculative parallelism, loosely based on:
2010-06-27 11:12:52 +04:00
2010-06-28 02:34:37 +04:00
* Prakash Prabhu, G. Ramalingam, and Kapil Vaswani, "*Safe Programmable Speculative Parallelism*",
In the proceedings of Programming Language Design and Implementation (PLDI) Vol 45, Issue 6 (June 2010) pp 50-61.
< http: / / research . microsoft . com / pubs / 118795 / pldi026-vaswani . pdf >
2010-06-27 11:12:52 +04:00
2010-06-28 02:57:10 +04:00
This package provides speculative function application and speculative folds. Speculative `STM` transactions take the place
2010-06-28 02:34:37 +04:00
of the transactional rollback machinery from the paper.
2010-06-27 23:57:37 +04:00
2010-06-28 02:57:10 +04:00
You can download it using `cabal install speculation` , if you have the Haskell Platform installed.
2010-06-27 19:02:55 +04:00
2010-06-28 02:30:18 +04:00
Speculative Function Application (Control.Concurrent.Speculation)
-----------------------------------------------------------------
2010-06-27 11:12:52 +04:00
2010-06-27 21:37:52 +04:00
Various speculative function application combinators are provided. Two fairly canonical samples are described here.
2010-06-27 19:02:55 +04:00
#### spec
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
spec :: Eq a => a -> (a -> b) -> a -> b
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
`spec g f a` evaluates `f g` while forcing `a` , if `g == a` then `f g` is returned. Otherwise `f a` is evaluated.
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
Furthermore, if the argument has already been evaluated, we avoid sparking the parallel computation at all.
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
If `g` is a good guess at the value of `a` , this is one way to induce parallelism in an otherwise sequential task.
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
However, if `g` isn\'t available more cheaply than `a` , then this saves no work, and if `g` is wrong, you risk evaluating the function twice.
spec a f a = f $! a
2011-11-09 09:26:35 +04:00
2010-06-27 19:02:55 +04:00
The best-case timeline looks like:
[---- f g ----]
[----- a -----]
[-- spec g f a --]
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
The worst-case timeline looks like:
[---- f g ----]
[----- a -----]
[---- f a ----]
[------- spec g f a -----------]
2011-11-09 09:26:35 +04:00
2010-06-28 09:27:12 +04:00
Compare these to the timeline of `f $! a` :
2010-06-27 19:02:55 +04:00
[---- a -----]
[---- f a ----]
2010-06-27 11:12:52 +04:00
2010-06-27 19:02:55 +04:00
#### specSTM
2010-06-27 11:12:52 +04:00
2010-06-28 02:57:10 +04:00
`specSTM` provides a similar compressed timeline for speculated `STM` actions, but also rolls back side-effects.
2010-06-27 11:12:52 +04:00
2010-06-28 02:30:18 +04:00
Speculative Folds (Data.Foldable.Speculation)
---------------------------------------------
2010-06-27 11:12:52 +04:00
2010-06-28 02:57:10 +04:00
A speculative version of the combinators from `Data.Foldable` is provided as `Data.Foldable.Speculation` .
2011-11-09 09:26:35 +04:00
2010-06-27 21:37:52 +04:00
Each combinator therein takes an extra argument that is used to speculate on the value of the list.
2010-06-27 11:12:52 +04:00
2010-06-27 21:37:52 +04:00
#### foldr
2010-06-27 19:02:55 +04:00
2010-06-27 21:37:52 +04:00
foldr :: (Foldable f, Eq b) => (Int -> b) -> (a -> b -> b) -> b -> f a -> b
2010-06-27 19:02:55 +04:00
2010-06-28 02:57:10 +04:00
Given a valid estimator `g` , `foldr g f z xs` yields the same answer as `Foldable.foldr' f z xs` .
2010-06-27 19:02:55 +04:00
2010-06-27 23:55:44 +04:00
`g n` should supply an estimate of the value returned from folding over the **last** `n` elements of the container.
2010-06-27 19:02:55 +04:00
2010-06-28 02:57:10 +04:00
As with `spec` , if the guess `g n` is accurate a reasonable percentage of the time and faster to compute than the ensuing fold, then this can provide increased opportunities for parallelism.
2010-06-27 19:02:55 +04:00
2010-06-27 21:37:52 +04:00
#### foldl
foldl :: (Foldable f, Eq b) => (Int -> b) -> (b -> a -> b) -> b -> f a -> b
2010-06-27 23:55:44 +04:00
`foldl` works similarly to `Foldable.foldl'` , except that `g n` should provide an estimate for the **first** `n` elements.
2010-06-27 21:37:52 +04:00
2010-06-27 23:57:37 +04:00
Contact Information
2010-06-27 21:37:52 +04:00
-------------------
2010-06-27 19:02:55 +04:00
2010-06-28 02:30:18 +04:00
Contributions and bug reports are welcome!
I can be reached through the user ekmett on github, as edwardk on irc.freenode.net #haskell channel, or by email at < ekmett @ gmail . com > .
2010-06-27 19:02:55 +04:00
2010-06-27 21:37:52 +04:00
-Edward Kmett