Transcript Document
CONCURRENCY RUNTIME FINISHING ERLANG
Christian Schulte
Software and Computer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden ID1218 Lecture 06 2009-11-16
Overview
2
Concurrent MiniErlang sketch how it really computes builds on MiniErlang Analyzing runtime asymptotic complexity, big-O notation analyzing recursive functions Wrapping up the Erlang part will return later as point for comparison ID1218, Christian Schulte L06, 2009-11-16
3
Processes With State
ID1218, Christian Schulte L06, 2009-11-16
Processes
4
Receive messages To be useful they need to maintain state changing over time Model: process is modeled by function
state
message
state
ID1218, Christian Schulte L06, 2009-11-16
5
Process States
messages receive
a a
s
0
s
1
s
2
a
… ID1218, Christian Schulte L06, 2009-11-16
Defining a Process With State
6
Process how it reacts to messages how it transforms the state from which initial state it starts Additionally process might compute by sending messages to other processes ID1218, Christian Schulte L06, 2009-11-16
Example: Logic of a Cell Process
7
cell({assign,New},S) -> New; cell({access,PID},S) -> PID ! {self(),S}, S.
Captures how the process transforms state how it acts to incoming messages ID1218, Christian Schulte L06, 2009-11-16
A Generic Process With State
8
serve(F,InS) -> receive Msg -> OutS = F(Msg,InS), serve(F,OutS) end.
cellserver() -> spawn(fun () -> serve(fun cell/2,0) end).
Can be started with function that performs state transitions initial value for state ID1218, Christian Schulte L06, 2009-11-16
Making The Server Smarter
9
serve(F,InS) -> receive kill -> void; … Msg -> OutS = F(Msg,InS), serve(F,OutS) end.
Add generic functionality to server ID1218, Christian Schulte L06, 2009-11-16
A Reconfigurable Server
10
Behavior of server defined by generic message receipt specific state transformation plus communication Idea: make server reconfigurable change how state is transformed adapt state to possibly new representation ID1218, Christian Schulte L06, 2009-11-16
A Reconfigurable Server
11
serve(F,InS) -> receive kill -> void; {update,NewF,Adapt} -> serve(NewF,Adapt(InS)); … Msg -> end.
OutS = F(Msg,InS), serve(F,OutS) ID1218, Christian Schulte L06, 2009-11-16
Buffered Cells
12
bcell({assign,V},{_,B}) -> {V,B}; bcell({access,PID},{V,B}) -> PID ! {self(),V}, {V,B}; bcell({save},{V,_}) -> {V,V}; bcell({restore},{_,B}) -> {B,B}.
Features states {V,B} with value V and buffer B ID1218, Christian Schulte L06, 2009-11-16
Reconfiguring the Server
13
> C=cellserver().
… > C ! {assign,4}.
… > C ! {update, fun bcell/2, fun (Old) -> {Old,0} end}.
… > C ! {save}. … ID1218, Christian Schulte L06, 2009-11-16
14
Coordination
ID1218, Christian Schulte L06, 2009-11-16
Protocols
15
Protocol: rules for sending and receiving messages programming with processes Examples broadcasting messages to group of processes choosing a process Important properties of protocols safety liveness ID1218, Christian Schulte L06, 2009-11-16
Choosing a Process
16
Example: choosing the best lift, connection, … More general: seeking agreement coordinate execution General idea: Master send message to all slaves containing reply PID select one slave: accept all other slaves: reject Slaves answer by replying to master PID wait for decision from master ID1218, Christian Schulte L06, 2009-11-16
Master: Blueprint
17
decide(SPs) -> Rs=collect(SPs,propose), {SP,SPr}=choose(SPs,Rs), SP ! {self(),accept}, broadcast(SPr,reject}.
Generic: collecting and broadcasting Specific: choose single process from processes based on replies Rs ID1218, Christian Schulte L06, 2009-11-16
Slave: Blueprint
18
slave() -> receive {M,propose} -> R=…, M ! {self(),R}, receive {M,accept} -> …; {M,reject} -> … end end ID1218, Christian Schulte L06, 2009-11-16
Avoiding Deadlock
19
Master can only proceed, after all slaves answered will not process any more messages until then receiving messages in collect Slave can only proceed, after master answered will not process any more messages until then What happens if multiple masters for same slaves?
ID1218, Christian Schulte L06, 2009-11-16
20
Deadlock
M N Master A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
21
Deadlock
M N Master A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
22
Deadlock
M N Master A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
23
Deadlock
M N Master blocks!
A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
24
Deadlock
M blocks!
N Master blocks!
A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
25
Deadlock
A M blocks!
B N Master blocks!
C M blocks A, waits for B D N blocks B, waits for A Deadlock!!!!
Slave ID1218, Christian Schulte L06, 2009-11-16
Avoiding Deadlock
26
Force all masters to send in order: First A, then B, then C, … Guarantee: If A available, all others will be available difficult: what if dynamic addition and removal of lists does not work with low-latency collect low-latency: messages can arrive in any order high-latency: receipt imposes strict order Use an adaptor access to slaves through one single master slaves send message to single master problem: potential bottleneck ID1218, Christian Schulte L06, 2009-11-16
27
Adaptor
M N Master A B C D Slave ID1218, Christian Schulte L06, 2009-11-16
Adaptor
28
adaptor() -> receive {decide,Client,PIDs} -> end.
decide(PIDs), Client ! self(), adaptor() % A is PID of adaptor process ndecide(A,PIDs) -> A ! {decide,self(),PIDs}, receive A -> void end.
Run single dedicated adaptor process master blocks until decision process has terminated ID1218, Christian Schulte L06, 2009-11-16
Liveness Properties
29
Important property of concurrent programs liveness An event/activity might fail to be live other activities consume all CPU power message box is flooded (denial of services) activities have deadlocked … Difficult: all possible interactions with other processes must guarantee liveness reasoning of all possible interactions ID1218, Christian Schulte L06, 2009-11-16
Summary
30
Protocols for coordinating processes Can lead to deadlocks Simple structure best Important: liveness guarantees ID1218, Christian Schulte L06, 2009-11-16
31
Process State Reconsidered
ID1218, Christian Schulte L06, 2009-11-16
Creating a Cell Process
32
cell() -> spawn(fun cell/2,0).
Cell process initialized with zero as state ID1218, Christian Schulte L06, 2009-11-16
A Simple Task
33
inc(C) -> C ! {access,self()}, receive {C,N} -> C ! {assign,N+1} end.
Increment the cell’s content by one get the old value put the new value Does this work?
NO! NO!
Why?
ID1218, Christian Schulte L06, 2009-11-16
A Simple Task Screwed…
34
C=cell(), P1=spawn(fun () inc(C) end), P2=spawn(fun () inc(C) end), … We insist on result being 2!
sometimes: 2 sometimes: 1 Why?
ID1218, Christian Schulte L06, 2009-11-16
Execution Sketch A: Good
35
Process 1 C receives {access,P1} Process 1 C receives {assign,1} Process 2 C receives {access,P2} Process 2 C receives {assign,2} value got: 0 value put: 1 value got: 1 value put: 2 ID1218, Christian Schulte L06, 2009-11-16
Execution Sketch A: Bad
36
Process 1 C receives {access,P1} Process 2 C receives {access,P2} Process 1 C receives {assign,1} Process 2 C receives {assign,1} value got: 0 value got: 0 value put: 1 value put: 1 ID1218, Christian Schulte L06, 2009-11-16
What Is Needed
37
We need to avoid that multiple access and assign operations get out of order We need to combine access and assign into one operation we can not guarantee that not interrupted we can guarantee that state is consistent we can guarantee that no other message is processed in between operation is called atomic ID1218, Christian Schulte L06, 2009-11-16
Cell With Exchange
38
cell({assign,New},S) -> New; cell({access,PID},S) -> PID ! {self(),S}, S; cell({exchange,PID},S) -> PID ! {self(),S}, receive {PID,NewS} -> NewS end.
ID1218, Christian Schulte L06, 2009-11-16
Incrementing Rectified
39
inc(C) -> C ! {exchange,self()}, receive {C,N} -> C ! {self(),N+1} end Important aspect no message will be received in between!
ID1218, Christian Schulte L06, 2009-11-16
State and Concurrency
40
Difficult to guarantee that state is maintained consistently in a concurrent setting Typically needed: atomic execution of several statements together Processes guarantee atomic execution ID1218, Christian Schulte L06, 2009-11-16
Other Approaches
41
Atomic exchange lowlevel hardware: test-and-set Locks: allow only one thread in a “critical section” monitor: use a lock together with a process generalizations to single writer/multiple reader ID1218, Christian Schulte L06, 2009-11-16
Locking Processes
42
Idea that is used most often in languages which rely on state Before state can be manipulated: lock must be acquired for example, one lock per object If process has acquired lock: can perform operations If process is done, lock is released ID1218, Christian Schulte L06, 2009-11-16
A Lockable Process
43
outside(F,InS) -> receive {acquire,PID} -> PID ! {ok,self()}, inside(F,InS,PID) end.
inside(F,InS,PID) -> receive {release,PID} -> outside(F,InS) {PID,Msg} -> inside(F,F(Msg,InS)); end.
ID1218, Christian Schulte L06, 2009-11-16
Safety Properties
44
Maintain state of processes in consistent fashion do not violate invariants to not compute incorrect results Guarantee safety by atomic execution exclusion of other processes ("mutual exclusion") ID1218, Christian Schulte L06, 2009-11-16
45
Concurrent MiniErlang (CME)
ID1218, Christian Schulte L06, 2009-11-16
Processes in CME
46
Computation state is a collection of processes
P
1
P
2 …
P n
every process must be reduced eventually (fairness) no order among processes (set of processes) A process is an extended MiniErlang machine Es ; Vs ;
n
; Ms expression stack
Es
value stack process identifier (PID) mailbox
Ms Vs
n
ID1218, Christian Schulte L06, 2009-11-16
CME: Values and Expressions
47
Values now also include PIDs V := int | [] | [ PIDs cannot not appear in expressions
V
1 Expressions E := … |
V
2 ] |
n
| self() | E 1 ,
E
2 | E 1 !
E
2 | receive Instructions CONS , CALL , SEND | spawn(
F
)
C
1 ; …; C
n
end ID1218, Christian Schulte L06, 2009-11-16
Sequential Composition
48
E
1 ,
E
2 Es ; Vs ;
n
; Ms →
E
1
E
2 Es ; Vs ;
n
; Ms
Pr
Pr
Decompose into individual statements obey order of statements To be read: pick fairly any process that matches this pattern ID1218, Christian Schulte L06, 2009-11-16
Self PID
49
self() Es ; Vs ;
n
→ Es ;
n
Vs ;
n
; Ms ; Ms
Pr Pr
Pushes process' own PID on the value stack ID1218, Christian Schulte L06, 2009-11-16
Process Spawning
50
spawn(
F
) Es ; Vs ;
n
→ Es ;
m
Vs ;
n
; Ms ; Ms
F
() ; ;
m
;
Pr Pr
Create new process with expression stack that executes call to F an empty value stack a fresh (not used elsewhere) PID
m
an empty mailbox ID1218, Christian Schulte L06, 2009-11-16
Process Termination
51
; V ;
n
; Ms →
Pr Pr
Delete process without expression to be evaluated single value on stack is ignored ID1218, Christian Schulte L06, 2009-11-16
Message Sending
52
E
1 !
E
2 Es ; Vs ;
n
→ ; Ms
Pr E
1
E
2 SEND Es ; Vs ;
n
; Ms
Pr
First evaluate destination, then message After that perform message sending ID1218, Christian Schulte L06, 2009-11-16
SEND Instruction
53
SEND Es ; V 1
m
Vs ;
n
Es’ ; Vs’ ;
m
; Ms’
Pr
→ ; Ms Es ; V 1 Vs ;
n
Es’ ; Vs’ ;
m
; Ms ; Ms’
V
1
Pr
Instruction sends and evaluates to message Semantics is stronger than Erlang behavior realistic: model messages in transit with FIFO ID1218, Christian Schulte L06, 2009-11-16
Message Selection
54
select(C 1 ; if C
i
… = H
i
; ->
C n
, M Ms, Ns) = s(B
i
), Ns
Ms
B i
is first matching clause, match(H
i
, M)=s select(C 1 ; … ;
C n
, M Ms, Ns) = select(C 1 ; … ; if no clause matches
C n
, Ms, Ns M) select(C 1 ; … ;
C n
, , Ns) = no Traverses messages in mailbox in order constructs mailbox with all messages but received one ID1218, Christian Schulte L06, 2009-11-16
Message Receipt
55
receive
C
1 ; → … ;
E
Es ; Vs ;
n
C n
end Es ; Vs ;
n
; Ns
Pr
if select(C 1 ; … ;
C n
, Ms, ) = E, Ns ; Ms
Pr
Process can only receive if matching message is found ID1218, Christian Schulte L06, 2009-11-16
CME Machine
56
Initial configuration: single process with expression we want to evaluate on expression stack Final configuration: no process can be reduced not common, computations continue forever ID1218, Christian Schulte L06, 2009-11-16
ME and CME Differences
57
Expressions in ME can be replaced by the value they can be evaluated to declarative: independent reasoning referential transparency Not true in CME message sending as side-effect concurrently coordinating: reason on interaction ID1218, Christian Schulte L06, 2009-11-16
58
Runtime Efficiency
ID1218, Christian Schulte L06, 2009-11-16
What Are the Questions?
59
Runtime efficiency what is it we are interested in?
why are we interested?
how to make statements on runtime and memory?
Clearly “faster” is better we have to know how fast our programs compute we have to know how much memory our programs require we have to know how “good” a program is ID1218, Christian Schulte L06, 2009-11-16
Statements on Runtime
60
Run your program for some example data sets on some computer, make a statement statement valid, if data set gets larger?
statement valid, if executed on different computer?
statement valid, if executed on same computer but slightly different configuration?
Testing is insufficient!
ID1218, Christian Schulte L06, 2009-11-16
Runtime Guarantees
61
Testing can never yield a guarantee on runtime!
We need a form to express runtime guarantees capture size of input data capture different computers/configurations ID1218, Christian Schulte L06, 2009-11-16
Runtime Guarantees
62
Express runtime in relation to input size T(n)
runtime function
where n is size of input for example integers lists argument length of list ID1218, Christian Schulte L06, 2009-11-16
Runtime Guarantees
63
We need to ignore marginal difference between runtime functions difference for small input sizes only consider for n ≥ n 0 difference by constant
c
1 T(n) same as
c
2 T(n) ID1218, Christian Schulte L06, 2009-11-16
Asymptotic Complexity
64
Asymptotic complexity is such a runtime guarantee: best
upper bound
on runtime up to a constant factor for sufficiently large inputs Discuss runtime by using “big-oh” notation ID1218, Christian Schulte L06, 2009-11-16
Big-Oh Notation
65
Assume T(n) f(n) runtime, n size of input function on non-negative integers T(n) is of O(f(n)) “T(n) is of order f(n)” iff T(n)
c
f(n) for all n≥n 0 for some c for some n 0 (whatever computer) (sufficiently large) ID1218, Christian Schulte L06, 2009-11-16
66
Big-Oh Notation
T
(
n
)
c
n
f(n) = n, c=2
n
0
n
T(n) is of O(f(n)) iff T(n) “T(n) is of order f(n)”
c
f(n) for all n≥n 0 for some c for some n 0 (whatever computer) (sufficiently large) ID1218, Christian Schulte L06, 2009-11-16
Big-Oh Notation
67
T(n) is of O(f(n)) sometimes written as T(n) = O(f(n)) T(n) O(f(n)) Examples T(n) = 4n + 42 T(n) = 5n + 42 T(n) = 7n + 11 T(n) = 4n + n 3 T(n) = n 100 + 2
n
+ 8 is is O(n) O(n) is is is O(n) O(n 3 ) O(2
n
) ID1218, Christian Schulte L06, 2009-11-16
Big-Oh Notation
68
Often one just says for O(n) O(n 2 ) O(n 3 ) O(log n) O(2
n
) linear complexity quadratic complexity cubic complexity logarithmic complexity exponential complexity ID1218, Christian Schulte L06, 2009-11-16
Summary
69
Formulate statements on runtime as
runtime guarantees asymptotic complexity
for large input independent of computer Expressed in big-oh notation abstracts away behavior of function for small numbers abstracts away constants captures asymptotic behavior of functions ID1218, Christian Schulte L06, 2009-11-16
70
Determining Complexity
ID1218, Christian Schulte L06, 2009-11-16
Approach
71
Take MiniErlang program Take execution time for each expression Give equations for runtime of functions Solve equations Determine asymptotic complexity ID1218, Christian Schulte L06, 2009-11-16
Simplification Here
72
We will only consider programs with one function Generalization to many functions straightforward complication: solving equation ID1218, Christian Schulte L06, 2009-11-16
Execution Times for Expressions
73
Give inductive definition based on function definition and structure of expressions Function definition pattern matching and guards Simple expression values and list construction More involved expression function call recursive function call leads to recursive equation often called: recurrence equation ID1218, Christian Schulte L06, 2009-11-16
Execution Time: T(E)
74
Value T(V) = c value List construction T( [
E
1 |
E
2 ] ) = c cons + T(E 1 ) + T(E 2 ) Time T(E) needed for executing expression E how MiniErlang machine executes E ID1218, Christian Schulte L06, 2009-11-16
75
Execution Time: T(E)
Value T(V) = c to ease notation, just forget subscript List construction T( [
E
1 |
E
2 ] ) = c + T(E 1 ) + T(E 2 ) Time T(E) needed for executing expression E how MiniErlang machine executes E ID1218, Christian Schulte L06, 2009-11-16
Function Call
76
For a function F define a function
T F
(n) and determine size of input for call to F input for a function for its runtime ID1218, Christian Schulte L06, 2009-11-16
Function Call
77
T(F (
E
1 , ...
,
E k
) ) = c call + T(E 1 ) + ... + T(E
k
) + T
F
(size(I
F
({1, ..., k}))) input arguments
I F
({1, ..., k}) input arguments for F size size(I
F
({1, ..., k})) size of input for F ID1218, Christian Schulte L06, 2009-11-16
Function Definition
78
Assume function F defined by clauses
H
1 -> B1 ; … ;
H k
->
B k
.
T F
(n) = c select + max { T(B 1 ), …, T(B
k
) } ID1218, Christian Schulte L06, 2009-11-16
Example: app/2
79
app([],Ys) -> Ys; app([X|Xr],Ys) -> [X|app(Xr,Ys)].
What do we want to compute
T
app (n) Knowledge needed input argument size function first argument length of list ID1218, Christian Schulte L06, 2009-11-16
80
Computing T
app
=T
a let’s use the whiteboard… ID1218, Christian Schulte L06, 2009-11-16
Append: Recurrence Equation
81
Analysis yields
T
app (0) = c 1
T
app (n) = c 2 + T app (n-1) Solution to recurrence is
T
app (n) = c 1 + c 2 Asymptotic complexity
n T
app (n) is of O(n) “linear complexity” ID1218, Christian Schulte L06, 2009-11-16
Recurrence Equations
82
Analysis in general yields a system T(n) T(0), T(1), … defined in terms of T(m 1 ), …, T(m
k
) for m 1 , …, m
k
< n values for certain n Possibilities solve recurrence equation (difficult in general) lookup asymptotic complexity for common case ID1218, Christian Schulte L06, 2009-11-16
Common Recurrence Equations
T(n)
c
+
T
(
n
–1)
c
1 +
c
2
n
+
T
(
n
–1)
c
+
T
(
n
/2)
c
1 +
c
2
n
+
T
(
n
/2)
c
+ 2
T
(
n
/2)
c
+ 2
T
(
n
-1)
c
1 +
c
2
n
+
T
(
n
/2) L06, 2009-11-16
Asymptotic Complexity
O(
n
) O(
n
2 ) O(log
n
)
O(n
) O(
n
) O(2
n
)
O(n
log
n
) ID1218, Christian Schulte
83
Example: Naïve Reverse
84
rev([]) -> []; rev([X|Xr]) -> app(rev(Xr),[X]).
Analysis yields
T
rev (0)= c 1
T
rev (n) = c 2 + T app (n-1) + T rev (n-1) = c 2 + c 3 (n-1) + T rev (n-1) Asymptotic complexity
T
rev (n) is of O(n 2 ) “quadratic complexity” ID1218, Christian Schulte L06, 2009-11-16
What Is to be Done?
85
Size functions and input functions Recurrence equation Finding asymptotic complexity …understanding of programs might be necessary… ID1218, Christian Schulte L06, 2009-11-16
Obs!
86
Making computations iterative can change runtime!
Can improve: Naïve reverse O(n 2 ) reverse O(n) Can be worse: appending lists O(n) appending lists O(n 2 ) ID1218, Christian Schulte L06, 2009-11-16
Judging Asymptotic Complexity
87
What does it mean?
good/bad?
even optimal?
Consider size of computed output if size is of same order:perfect?
otherwise: O(n log n) is very good (optimal for sorting) check book on algorithms Very difficult problem!
ID1218, Christian Schulte L06, 2009-11-16
Hard Problems
88
Computer science is tough business Most optimization, combinatorial problems are
hard
(non-tractable) problems Graph coloring minimal number of colors no connected node has same color used in: compilation, frequency allocation, … Travelling salesman ID1218, Christian Schulte L06, 2009-11-16
Hard Problems
89
NP problems: easy (polynomial complexity) for checking whether a certain candidate is a solution to problem much harder:
finding
a solution NP-complete problems: as hard as any other NP complete problem strong suspicion: no polynomial algorithm for finding a solution exists examples: graph coloring, satisfiability testing, cryptography, … ID1218, Christian Schulte L06, 2009-11-16
Summary: Runtime Efficiency
90
Asymptotic complexity gives runtime guarantee abstract from constants for all possible input given in Big-Oh notation Computing asymptotic complexity Think about meaning of asymptotic complexity ID1218, Christian Schulte L06, 2009-11-16
91
Summary: Part 1
ID1218, Christian Schulte L06, 2009-11-16
Functional Programming in Erlang
92
Functions defined by clauses clauses have patterns and guards Execution evaluates expressions declarative Expressions: values and function call Pattern matching for clause selection powerful for symbolic computation ID1218, Christian Schulte L06, 2009-11-16
MiniErlang
93
Model for functional Erlang that captures memory consumption in particular stack space for function calls MiniErlang machine gives operational semantics Identifies iterative computations run with constant stack space captures tail recursion Model for runtime analysis ID1218, Christian Schulte L06, 2009-11-16
Functional Programming Techniques
94
Pattern matching for execution control Accumulators make more functions tail recursive Higher-order functions pass functions as parameters separate generic from specific aspects ID1218, Christian Schulte L06, 2009-11-16
Concurrent Programming in Erlang
95
Message-passing between concurrent processes fair execution of processes fully buffered message delivery processes with identity Programmable receipt of messages in particular: pick messages by sending process with possibility of timeout ID1218, Christian Schulte L06, 2009-11-16
Concurrent Programming Techniques
96
Sending messages: asynchronous, synchronous Communication patterns asynchronous broadcasting synchronous broadcasting: low latency versus order choosing processes Avoiding deadlocks order recipients, introduce concurrency adaptors Essential properties liveness safety ID1218, Christian Schulte L06, 2009-11-16
Other Things in Erlang
97
Exception handling Distributed programming Fault-tolerant programming ID1218, Christian Schulte L06, 2009-11-16