Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 51 additions & 21 deletions lectures/numba.md
Original file line number Diff line number Diff line change
Expand Up @@ -687,19 +687,20 @@ effort to compute the constant $\pi$ by Monte Carlo.

Now try adding parallelization and see if you get further speed gains.

You should not expect huge gains here because, while there are many
independent tasks (draw point and test if in circle), each one has low
execution time.
There are many independent tasks here (draw a point and test whether it falls
in the circle), but each one has very low execution time.

Generally speaking, parallelization is less effective when the individual
tasks to be parallelized are very small relative to total execution time.
Generally speaking, parallelization is less effective when the individual tasks
are very small relative to the overheads of spreading them across multiple CPUs.

This is due to overheads associated with spreading all of these small tasks across multiple CPUs.
The way around this is to give each thread enough work to make those overheads
worth paying.

Nevertheless, with suitable hardware, it is possible to get nontrivial speed gains in this exercise.
So, for the size of the Monte Carlo simulation, use something substantial, such
as `n = 100_000_000`.

For the size of the Monte Carlo simulation, use something substantial, such as
`n = 100_000_000`.
At that scale, and with suitable hardware, you should see a clear gain over the
serial version.
```

```{solution-start} numba_ex3
Expand All @@ -723,36 +724,65 @@ def calculate_pi_parallel(u_draws, v_draws):
return area_estimate * 4 # dividing by radius**2
```

Now let's see how fast it runs:
Parallelization pays off when each thread has enough work to overcome the overhead costs while
breaking the problem into parts for work to happen simultaneously.

Let's draw a fresh, much larger set of points rather than reusing the arrays from above.

```{note}
The two arrays below occupy about 1.6 GB of memory — reduce `n` if your
machine is short on RAM.
```

```{code-cell} ipython3
n = 100_000_000
rng = np.random.default_rng()
u_big = rng.uniform(size=n)
v_big = rng.uniform(size=n)
```

Now let's see how fast it runs (the second call measures runtime without
compilation time):

```{code-cell} ipython3
with qe.Timer():
calculate_pi_parallel(u_draws, v_draws)
calculate_pi_parallel(u_big, v_big)
```

```{code-cell} ipython3
with qe.Timer():
calculate_pi_parallel(u_draws, v_draws)
calculate_pi_parallel(u_big, v_big)
```

By switching parallelization on and off (selecting `True` or
`False` in the `@jit` annotation), we can test the speed gain that
multithreading provides on top of JIT compilation.
For comparison, here is the serial jitted version from {ref}`speed_ex1` on the
same points:

```{code-cell} ipython3
with qe.Timer():
calculate_pi(u_big, v_big)
```

Comment thread
mmcky marked this conversation as resolved.
On our workstation, we find that parallelization provides a modest but
worthwhile speed gain here.
Comparing the last two timings, multithreading provides a substantial speed
gain on top of JIT compilation.

(If you are executing locally, you will get different results, depending mainly
on the number of CPUs on your machine.)
on the number of CPUs on your machine — and at small sample sizes the
parallel version can even be slower, because the gains cannot cover the cost of
distributing work across threads.)

These two arrays are large and we are finished with them, so we release the
memory before moving on.

```{code-cell} ipython3
del u_big, v_big
```

Notice that we drew all of the random points *before* the loop and passed them in
as arrays, so the parallel loop only *reads* from memory.

Drawing the points *inside* the parallel loop instead is surprisingly delicate.


We investigate why, and how to do it safely, in
{ref}`numba_ex_race`.
We investigate why, and how to do it safely, in {ref}`numba_ex_race`.

```{solution-end}
```
Expand Down
Loading