You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -5,20 +5,21 @@ Multicore OCaml. All the code examples along with their corresponding dune file
5
5
are available in the `code/` directory. The tutorial is organised into the
6
6
following sections:
7
7
8
-
*[Introduction](#introduction)
9
-
*[Installation](#installation)
10
-
*[Domains](#domains)
11
-
*[Domainslib](#domainslib)
12
-
*[Task pool](#task-pool)
13
-
*[Parallel for](#parallel-for)
14
-
*[Async-Await](#async-await)
15
-
*[Channels](#channels)
16
-
*[Bounded Channels](#bounded-channels)
17
-
*[Task Distribution using Channels](#task-distribution-using-channels)
18
-
*[Profiling your code](#profiling-your-code)
19
-
*[Perf](#perf)
20
-
*[Eventlog](#eventlog)
21
-
8
+
-[Introduction](#introduction)
9
+
*[Installation](#installation)
10
+
*[Compatibility with existing code](#compatibility-with-existing-code)
11
+
-[Domains](#domains)
12
+
-[Domainslib](#domainslib)
13
+
*[Task pool](#task-pool)
14
+
*[Parallel for](#parallel-for)
15
+
*[Async-Await](#async-await)
16
+
+[Fibonacci numbers in parallel](#fibonacci-numbers-in-parallel)
17
+
-[Channels](#channels)
18
+
*[Bounded Channels](#bounded-channels)
19
+
*[Task Distribution using Channels](#task-distribution-using-channels)
20
+
-[Profiling your code](#profiling-your-code)
21
+
*[Perf](#perf)
22
+
*[Eventlog](#eventlog)
22
23
23
24
# Introduction
24
25
@@ -27,6 +28,13 @@ Parallelism through `Domains` and Concurrency through `Algebraic effects`. It is
27
28
slowly, but steadily being merged to trunk OCaml. Domains-only multicore is
28
29
expected to land first followed by Algebraic effects.
29
30
31
+
**Concurrency** is how we partition multiple computations such that they can
32
+
run in overlapping time periods rather than strictly sequentially.
33
+
**Parallelism** is the act of running multiple computations simultaneously,
34
+
primarily by using multiple cores on a multicore machine. The multicore wiki
35
+
has [comprehensive notes](https://github.com/ocaml-multicore/ocaml-multicore/wiki/Concurrency-and-parallelism-design-notes) on the design decisions and
36
+
current status of concurrency and parallelism in Multicore OCaml.
37
+
30
38
The Multicore OCaml compiler comes with two variants of Garbage Collector,
31
39
namely a concurrent minor collector (ConcMinor) and a stop-the-world parallel
32
40
minor collector (ParMinor). Our experiments have shown us that ParMinor
@@ -35,7 +43,8 @@ need any changes in the C API of the compiler, unlike ConcMinor which breaks
35
43
the C API. So, the consensus is to go forward with ParMinor during up-
36
44
streaming of the Domains-only Multicore. ConcMinor is at OCaml version `4.06.1`
37
45
and ParMinor has been promoted to `4.10.0` and `4.11.0`. More details on the GC
38
-
design and evaluation are available in [this paper](https://arxiv.org/abs/2004.11663).
The Multicore ecosystem also has the following libraries to complement the
41
50
compiler.
@@ -51,19 +60,27 @@ Multicore OCaml
51
60
swap library
52
61
53
62
This tutorial takes you through ways in which one can profitably write parallel
54
-
programs in Multicore OCaml. The effect handlers story is not touched upon
63
+
programs in Multicore OCaml. A reader is assumed to be familiar with OCaml, if
64
+
not, they are encouraged to read [Real World OCaml](https://dev.realworldocaml.org/toc.html). The effect handlers story is not touched upon
55
65
here, for anyone interested, do check out this [tutorial](https://github.com/ocamllabs/ocaml-effects-tutorial) and [examples](https://github.com/ocaml-multicore/effects-examples).
56
66
57
67
## Installation
58
68
59
-
While up-streaming of the multicore bits to trunk is still work in progress, one
60
-
can start using Multicore OCaml with the help of [multicore-opam](https://github.com/ocaml-multicore/multicore-opam). Installation instructions for
69
+
Up-streaming of the multicore bits to trunk OCaml in progress, with [some PRs already merged to trunk](https://github.com/ocaml/ocaml/pulls?q=is%3Apr+label%3Amulticore-prerequisite+).
70
+
One can start using Multicore OCaml with the help of [multicore-opam](https://github.com/ocaml-multicore/multicore-opam). Installation instructions for
61
71
Multicore OCaml 4.10.0 compiler and domainslib can be found [here](https://github.com/ocaml-multicore/multicore-opam#install-multicore-ocaml).
62
72
Other available compiler variants are [here](https://github.com/ocaml-multicore/multicore-opam/tree/master/packages/ocaml-variants).
63
73
64
74
It will also be useful to install `utop` on your Multicore switch.
65
75
`opam install utop` should work out of the box.
66
76
77
+
## Compatibility with existing code
78
+
79
+
Multicore OCaml is compatible with existing OCaml code. It has support for the
80
+
C API along with some tricky parts of the language like ephemerons and
81
+
finalisers. To maintain compatibility with `ppx` there is a `no-effect-syntax`
82
+
compiler variant in multicore-opam, that removes some syntax extensions.
83
+
67
84
# Domains
68
85
69
86
Domains are the basic unit of parallelism in Multicore OCaml.
@@ -129,8 +146,8 @@ Error: Unbound module Atomic
129
146
Error: Library "domainslib" not found.
130
147
```
131
148
132
-
These errors usually mean that the switch used to compile the code is not a
133
-
multicore switch. Using a multicore switch should resolve them.
149
+
These errors usually mean that the compiler switch used to compile the code is
150
+
not a multicore switch. Using a multicore compiler variant should resolve them.
134
151
135
152
# Domainslib
136
153
@@ -184,19 +201,20 @@ after all tasks are done.
184
201
185
202
## Parallel for
186
203
187
-
`parallel_for` is a powerful primitive in the Task API that can scale well with
188
-
very little change in sequential code.
204
+
`parallel_for` is a powerful primitive in the Task API which can be used to
205
+
parallelise computations that use for loops. It can scale well with very little
206
+
change to the sequential code.
189
207
190
208
Let us consider the example of matrix multiplication.
191
209
192
-
First, let us write the sequential version of a function which performs matrix
193
-
multiplication of two matrices and returns the result.
210
+
First, let us write down the sequential version of a function which performs
211
+
matrix multiplication of two matrices and returns the result.
194
212
195
213
```ocaml
196
-
let multiply_matrix a b =
214
+
let matrix_multiply a b =
197
215
let i_n = Array.length a in
198
216
let j_n = Array.length b.(0) in
199
-
let k_n = Array.length b
217
+
let k_n = Array.length b in
200
218
let res = Array.make_matrix i_n j_n 0 in
201
219
for i = 0 to i_n - 1 do
202
220
for j = 0 to j_n - 1 do
@@ -208,11 +226,30 @@ let multiply_matrix a b =
208
226
res
209
227
```
210
228
211
-
Arrays offer better efficiency compared with lists in the context of Multicore
212
-
OCaml. Although they are not generally favoured in functional programming, using
213
-
arrays for the sake of efficiency is a reasonable trade-off.
229
+
To make this function run in parallel, one might be inclined to spawn a new
230
+
domain for every iteration in the loop, which would look like:
214
231
215
-
We shall parallelise matrix multiplication with the help of a `parallel_for`.
0 commit comments