Efficient Parallel Programming with F# and Hopac
Natallia Dzenisenka
@nata_dzen
Terminology
Synchronous, serial, blocking
All operations are performed one by one.
Asynchronous, non-blocking
Doing something useful while waiting. It is widely used for UI. May not provide performance benefits.
Parallel
Execution of several tasks at the same time unit, provides performance benefits.
Concurrent
Execution of several tasks.
Synchronous, serial, blocking
CODE
WAITING
As if you write your code till it's complete, wait for it to compile and then drink coffee
Asynchronous, non-blocking
CODE
…
Write your code and then drink coffee at the same time while waiting for compilation
Parallel
CODE
Listening to music while coding: you can do both at the same time unit.
Concurrent
CODE
CODE
CODE
You can’t text your boss at the exact same time as you write code, but you’re basically doing both things
Why F#?
Because F# is a functional programming language where asynchronous programming is very easy;
Monads in F# are implemented as computation expressions;
F# has async {} computation expression.
Async computation expression
let testAsync = async{
...
let! result = someAsyncOperation
...
}
Why Hopac?
Because it provides:
When is the best time to use Hopac?
Why “Hopac”?
Authentically known Legend of Hopac
Hopac is also a national Ukrainian dance
What my Ukrainian friends think I’m doing when I say “I’m working on my Hopac”
What I’m actually doing...
Let’s code!
Matrix Multiplication
1
2
3
4
5
6
7
8
9
1
8
7
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
9
6
5
4
3
2
1
30
24
18
84
69
54
138
114
90
C (3x3)
B (3x3)
A (3x3)
C[1,1] = 1 x 9 + 2 x 6 + 3 x 3 = 30
C[i,j] = C[i,j] + A[i,k] * B[k,j]
Regular Matrix Multiplication
Async Matrix Multiplication
Task Parallel Matrix Multiplication
Hopac Matrix Multiplication
Results: 10x10 matrix
Results: 500x500 matrix
Results: 1000x1000 matrix
Results: 2000x2000 matrix
Results: 2000x2000 matrix�Larger Machine
Results of Matrix Multiplication example
Matrix 2000 x 2000 results on Large Machine
Recursive sum of the tree
1
2
3
4
5
6
7
11
8
9
10
15
12
13
14
Sum = 1 + 2 + 3… + 15 = 120
1
2
3
4
Level
Tree structure
Serial or Synchronous
Async
Tasks
Hopac
Results: Tree of 1,023 elements
Results: Tree of 32,767 elements
Results: Tree of 1,048,575 elements
Results: Tree of 8,388,607 elements
Results of Sum of the Tree example
Results of Sum of the Tree example
Primitives
Ch<‘x> - Channel
Alt<‘x> - Alternative
Creation of a Job
Job of performing a Talk
Three talks at the same time
Group picture
Attempt to take group picture at the end of all talks
Attempt to take group picture at the end of all talks
Taking group picture
Good group picture
Waiting for any talk
Waiting for any talk
Recall Sum of a Tree
Different notation
Infixes
<*> performs two jobs in parallel
>>- runs given job and then passes result to a function on the right and runs it.
>>-. some value will be returned
>>= creates a job that first runs the given job and then passes the result of that job to the given function to build another job which will then be run.
>>=. creates a job that runs the given two jobs and returns the result of the second job.
...Many more
Channels
message passing primitives
Alternatives
Ch.take aChannel
Ch.give aChannel aValue
do! Ch.give aChannel aValue
let! aValue = Ch.take aChannel
Alt Timeout
Alt from Promise.read
Alt.choose
Even more infixes
Negative Acknowledgements
Nack example
Nack example running
Thank you!
�Natallia Dzenisenka�@nata_dzen