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

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

Dec 19, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Parallelism and Concurrency

Koen Lindström ClaessenChalmers UniversityGothenburg, Sweden

Ulf Norell

Page 2: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Parallel Strategies

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

Page 11: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

More ...

Implemented in GHCControl.ParallelControl.Parallel.Strategies

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

Page 12: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Concurrent Programming

ProcessesConcurrencyParallelism

Shared resourcesCommunicationLocksBlocking

Page 13: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Problems With Locking

RacesForgotten lock

DeadlockGrabbing/releasing locks in wrong order

Error recovery InvariantsLocks

Page 17: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Software Transactional Memory (STM)

First ideas in 1993 New developments in 2005

Simon Peyton JonesSimon MarlowTim HarrisMaurice Herlihy

Page 23: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Atomic Transactions

action3 = atomically { withdraw a 100 deposit b 100 }

”write sequential code, and wrap

atomically around it”

Page 24: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Simon’s Missile Program

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

No side effects allowed!

Page 28: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Example

type 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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Example

retry :: 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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Compositional Choice

orElse :: 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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

Example: MVars

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

Page 36: Parallelism and Concurrency Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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 Koen Lindström Claessen Chalmers University Gothenburg, Sweden Ulf Norell.

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