[1]:

import numpy as np
import boost_histogram as bh
from functools import reduce
from numpy.testing import assert_array_equal


This notebook explores parallel filling by hand (not using the threads= argument).

[2]:

hist_linear = bh.Histogram(bh.axis.Regular(100, 0, 1))
hist_atomic = bh.Histogram(bh.axis.Regular(100, 0, 1), storage=bh.storage.AtomicInt64())

vals = np.random.rand(10_000_000)


[3]:

%%timeit
hist_linear.reset()
hist_linear.fill(vals)

25.5 ms ± 774 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)


This is a single threaded atomic fill.

[4]:

%%timeit
hist_atomic.reset()
hist_atomic.fill(vals)

59.9 ms ± 2.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


This is a threaded fill (storage not threadsafe, so will get the wrong result; just for comparison)

This is a threaded fill, this time with atomics. It may not be faster, but is useful in situations where you are filling from multiple places in your code.

[5]:

%%timeit
hist_atomic.reset()
pool.submit(hist_atomic.fill, chunk)

61.2 ms ± 1.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


This makes four separate histograms, then fills them and adds at the end.

[6]:

def fun(x):
hist = bh.Histogram(bh.axis.Regular(100, 0, 1))
return hist.fill(x)

[7]:

%%timeit

8.12 ms ± 90 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)