parallelism and concurrency

38
Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell

Upload: oren

Post on 24-Feb-2016

76 views

Category:

Documents


0 download

DESCRIPTION

Parallelism and Concurrency. Ulf Norell. Koen Lindström Claessen Chalmers University Gothenburg, Sweden. Expressing Parallelism. In a pure, lazy language Evaluation is done when needed Evaluation order does not affect meaning of program One can do more work than what is needed. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Parallelism and Concurrency

Parallelism and Concurrency

Koen Lindström ClaessenChalmers UniversityGothenburg, Sweden

Ulf Norell

Page 2: Parallelism and Concurrency

Expressing Parallelism

In a pure, lazy languageEvaluation is done when neededEvaluation order does not affect meaning of

programOne can do more work than what is needed

Page 3: Parallelism and Concurrency

Two Primitives

seq :: a -> b -> b

par :: a -> b -> b

seq x y: Evaluate x first, and then

return y

par x y: Evaluate x in parallel, and

immediately return y

Page 4: Parallelism and Concurrency

Example

f’ x y z = x `par` y `par` z `par` f x y z

Idea: Write normal program first, then add parallelism to

speed it up

Page 5: Parallelism and Concurrency

QuickSort

qsort :: (Ord a) => [a] -> [a]qsort [] = []qsort [x] = [x]qsort (x:xs) = losort `par` hisort `par` losort ++ (x:hisort) where losort = qsort [y | y <- xs, y < x ] hisort = qsort [y | y <- xs, y >= x ]

Page 6: Parallelism and Concurrency

QuickSort (II)qsort :: (Ord a) => [a] -> [a]qsort [] = []qsort [x] = [x]qsort (x:xs) = force losort `par` force hisort `par` losort ++ (x:hisort) where losort = qsort [y | y <- xs, y < x ] hisort = qsort [y | y <- xs, y >= x ]

force :: [a] -> ()force [] = ()force (x:xs) = x `seq` force xs

Page 7: Parallelism and Concurrency

Parallel Map

pmap :: (a -> b) -> [a] -> [b]pmap f [] = []pmap f (x:xs) = fx `par` fxs `par` fx:fxs where fx = f x fxs = pmap f xs

Page 8: Parallelism and Concurrency

Parallel Strategies

type Done = ()type Strategy a = a -> Done

using :: a -> Strategy a -> aa `using` strat = strat a `seq` a

Page 9: Parallelism and Concurrency

Parallel Strategies

inSeq, inPar :: a -> Strategy binSeq x = \y -> x `seq` ()inPar x = \y -> x `par` ()

parList :: Strategy a -> Strategy [a]parList strat [] = ()parList strat (x:xs) = strat x `par` parList strat xs

Page 10: Parallelism and Concurrency

Parallel Strategies

pmap :: Strategy b -> (a -> b) -> [a] -> [b]pmap strat f xs = map f xs `using` parList strat

Page 11: Parallelism and Concurrency

More ...

Implemented in GHCControl.ParallelControl.Parallel.Strategies

Also look at:Control.Concurrent (-threaded)Control.Monad.STM

Page 12: Parallelism and Concurrency

Concurrent Programming

ProcessesConcurrencyParallelism

Shared resourcesCommunicationLocksBlocking

Page 13: Parallelism and Concurrency

Concurrent Haskell (v1.0)Control.Concurrent

fork :: IO a -> IO Pidkill :: Pid -> IO ()

type MVar a

newEmptyMVar :: IO (MVar a)takeMVar :: MVar a -> IO aputMVar :: MVar a -> a -> IO ()

starting/killing processes

a shared resource

blocking actions

Page 14: Parallelism and Concurrency

Concurrent Haskell (v1.0)Control.Concurrent.Chan

type Chan a

newChan :: IO (Chan a)readChan :: Chan a -> IO awriteChan :: Chan a -> a -> IO ()

an unbounded

channel

Page 15: Parallelism and Concurrency

Typical Concurrent Programming Today Use MVars (or similar concepts) to

implement ”locks”Grab the lock

Block if someone else has itDo your thingRelease the lock

Page 16: Parallelism and Concurrency

Problems With Locking

RacesForgotten lock

DeadlockGrabbing/releasing locks in wrong order

Error recovery InvariantsLocks

Page 17: Parallelism and Concurrency

The Biggest Problem

Locks are not compositional! Compositional = build a working system from

working pieces

action1 = withdraw a 100 action2 = deposit b 100

action3 = do withdraw a 100 deposit b 100

Inconsistent state

Page 18: Parallelism and Concurrency

Solution (?)

Expose the locks

action3 = do lock a lock b withdraw a 100 deposit b 100 release a release b

Danger of deadlock!

if a < b then do lock a; lock b else do lock b; lock a

Page 19: Parallelism and Concurrency

More Problems

action4 = do ...

action5 = do ...

action6 = action4 AND action5

Impossible!

Need to keep track of all locks of an action, and compose these

Page 20: Parallelism and Concurrency

Conclusion

Programming with locks isNot compositionalNot scalableGives you a head acheLeads to code with errors ...

A new concurrent programming paradigm is sorely needed

Page 21: Parallelism and Concurrency

Idea

Borrow ideas from database peopleTransactions

Add ideas from functional programmingComputations are first-class valuesWhat side-effects can happen where is

controlled Et voila!

Page 22: Parallelism and Concurrency

Software Transactional Memory (STM)

First ideas in 1993 New developments in 2005

Simon Peyton JonesSimon MarlowTim HarrisMaurice Herlihy

Page 23: Parallelism and Concurrency

Atomic Transactions

action3 = atomically { withdraw a 100 deposit b 100 }

”write sequential code, and wrap

atomically around it”

Page 24: Parallelism and Concurrency

How Does It Work?

Execute body without locks Each memory acces is logged No actual update is performed At the end, we try to commit the log to

memory Commit may fail, then we retry the whole

atomic block

action3 = atomically { withdraw a 100 deposit b 100 }

Page 25: Parallelism and Concurrency

Transactional Memory

No locks, so no race conditions No locks, so no deadlocks Error recovery is easy; an exception

aborts the whole block and retries Simple code, and scalable

Page 26: Parallelism and Concurrency

Caveats

Absolutely forbidden:To read a transaction variable outside an

atomic blockTo write to a transaction variable outside an

atomic blockTo make actual changes inside an atomic

block...

Page 27: Parallelism and Concurrency

Simon’s Missile Program

action3 = atomically { withdraw a 100 launchNuclearMissiles deposit b 100 }

No side effects allowed!

Page 28: Parallelism and Concurrency

STM HaskellControl.Concurrent.STM

First (and so far only?) fully-fledged implementation of STM

Implementations for C++, Java, C# on the way...Difficult to solve the problems

In Haskell, it is easy!Controlled side-effects

Page 29: Parallelism and Concurrency

STM HaskellControl.Concurrent.STM

type STM ainstance Monad STM

type TVar anewTVar :: a -> STM (TVar a)readTVar :: TVar a -> STM awriteTVar :: TVar a -> a -> STM ()

atomically :: STM a -> IO a

Page 30: Parallelism and Concurrency

Exampletype Resource = TVar Int

putR :: Resource -> Int -> STM ()putR r i = do v <- readTVar r writeTVar r (v+i)

main = do ... atomically (putR r 13) ...

Page 31: Parallelism and Concurrency

Exampleretry :: STM a

getR :: Resource -> Int -> STM ()getR r i = do v <- readTVar r if v < i then retry else writeTVar r (v-i)

main = do ... atomically (do getR r1 4 putR r2 4) ...

Page 32: Parallelism and Concurrency

Retrying

An atomic block is retried whenThe programmer says soThe commit at the end fails

Before retrying, we wait until one of the variables used in the atomic block is changedWhy? Referential

transparency!

Page 33: Parallelism and Concurrency

Compositional ChoiceorElse :: STM a -> STM a -> STM a

main = do ... atomically (getR r1 4 `orElse` getR r2 4) ...

m1 `orElse` (m2 `orElse` m3) = (m1 `orElse` m2) `orElse` m3retry `orElse` m = mm `orElse` retry = m

Page 34: Parallelism and Concurrency

Blocking or not?

nonBlockGetR :: Resource -> Int -> STM BoolnonBlockGetR r i = do getR r i return True `orElse` return False

Choice of blocking/non-blocking up to the

caller, not the method itself

Page 35: Parallelism and Concurrency

Example: MVars

MVars can be implemented using TVars type MVar a = TVar (Maybe a)

Page 36: Parallelism and Concurrency

New Things in STM Haskell

Safe transactions through type safetyDegenerate monad STM

We can only access TVars TVars can only be accessed in STM monad

Referential transparency Explicit retry -- expressiveness Compositional choice -- expressiveness

Page 37: Parallelism and Concurrency

Problems in C++/Java/C#

Retry semantics IO in atomic blocks Access of transaction variables outside of

atomic blocks Access to regular variables inside of

atomic blocks

Page 38: Parallelism and Concurrency

STM HaskellControl.Concurrent.STM

type STM ainstance Monad STM

type TVar anewTVar :: a -> STM (TVar a)readTVar :: TVar a -> STM awriteTVar :: TVar a -> a -> STM ()

atomically :: STM a -> IO aretry :: STM aorElse :: STM a -> STM a -> STM a