Mitsutoshi Aoe
March 31, 2013
450

# ekmett/speculation

March 31, 2013

## Transcript

1. ekmett/speculation
Mitsutoshi Aoe
@ma0e
13೥3݄31೔೔༵೔

2. ekmett/speculation
Safe Programmable Speculative Parallelism, PLDI 2010
http://hackage.haskell.org/package/speculation/
https://github.com/ekmett/speculation
13೥3݄31೔೔༵೔

3. Motivating examples
Inherently sequential algorithms
Lexing
Huffman decoding
13೥3݄31೔೔༵೔

4. Timeline - the best-case
a
f g
spec g f a
g == a
spec :: Eq a 㱺 a → (a → b) → a → b)
13೥3݄31೔೔༵೔

5. Timeline - the worst-case
a
f g
spec g f a
g /= a
spec :: Eq a 㱺 a → (a → b) → a → b)
f a
13೥3݄31೔೔༵೔

6. Timeline - under high load
a
spec g f a
g == a
spec :: Eq a 㱺 a → (a → b) → a → b)
f a
f \$! a
13೥3݄31೔೔༵೔

7. Speculation in Haskell
spec :: Eq a 㱺 a ! (a ! b) ! a ! b
spec guess f a = speculation `par`
if guess == a
then speculation
else f a
where
speculation = f guess
13೥3݄31೔೔༵೔

8. Speculation in Haskell
spec :: Eq a 㱺 a ! (a ! b) ! a ! b
spec guess f a =
| unsafeIsEvaluated a = f a
| otherwise = speculation `par`
if guess == a
then speculation
else f a
where
speculation = f guess
13೥3݄31೔೔༵೔

9. Speculation in Haskell
spec :: Eq a 㱺 a ! (a ! b) ! a ! b
spec guess f a =
| unsafeIsEvaluated a = f a
| numCapabilities == 1 = f \$! a
| otherwise = speculation `par`
if guess == a
then speculation
else f a
where
speculation = f guess
13೥3݄31೔೔༵೔

10. Speculating STM
specSTM :: Eq a
㱺 STM a ! (a ! STM b) ! a ! STM b
specSTM mguess f a = a `par` do
guess ← mguess
result ← f guess
unless (guess == a) retry
return result
`orElse`
f a
13೥3݄31೔೔༵೔

11. Speculating STM
specSTM :: Eq a
㱺 STM a ! (a ! STM b) ! a ! STM b
specSTM mguess f a = do
sparks ← unsafeIOToSTM numSparks
if sparks < numCapabilities
then a `par` do
guess ← mguess
result ← f guess
unless (guess == a) retry
return result
`orElse` f a
else f \$! a
13೥3݄31೔೔༵೔

12. C.C.Speculation.Foldable
foldr :: (Foldable f, Eq b)
㱺 (Int ! b) ! (a ! b ! b)
! b ! f a ! b
foldr g f z =
extractAcc . F.foldr mf (Acc 0 z)
where
mf a (Acc n b) = Acc
(n + 1)
(spec (g n) (f a) b)
data Acc a = Acc {-# UNPACK #-} !Int a
extractAcc (Acc _ a) = a
13೥3݄31೔೔༵೔

13. C.C.Speculation.Traversable
traverse
:: (Traversable t, Applicative f, Eq a)
㱺 (Int ! a) ! (a ! f b) ! t a ! f (t b)
traverse g f xs =
runAccT (T.traverse go xs) 0
where
go a = AccT \$ λi# ! acc
(i# +# 1#)
(spec (g (I# i)) f a)
newtype AccT m a = AccT
{ runAccT :: Int# ! Acc (m a) }
13೥3݄31೔೔༵೔

14. C.C.Speculation.List
scanr :: Eq b 㱺 (Int ! b)
! (a ! b ! b) ! b ! [a] ! [b]
scanr g f z
= map extractAcc
. L.scanr mf (Acc 0 z)
where
mf a (Acc n b) =
let n’ = n + 1
in Acc n’ (spec (g n’) (f a) b)
13೥3݄31೔೔༵೔

15. C.C.Speculation.Class
class MonadSpec m where
specByM
:: (a ! a ! Bool) ! a ! a ! m b
specByM’
:: (a ! a ! Bool) ! a ! a ! m b
specM :: (MonadSpec m, Eq a)
㱺 a ! a ! m a
13೥3݄31೔೔༵೔

16. Speed optimizations
unsafeIsEvaluated :: a ! Bool
ekmett/tag-bits
numSparks#
:: State# s ! (# State# s, Int# #)
since GHC 7 (#4167)
13೥3݄31೔೔༵೔

17. Demo
Speculative lexing from “Parallelizing the Web Browser”
https://gist.github.com/maoe/5279239
13೥3݄31೔೔༵೔