Years ago I wrote a math library with numba to do vectorized operations on large arrays of elements (example: multiply two array of matrices). I recently opened it up to experiment with parallelism (feature which did not exist at the time). In doing so there was a speed improvement but not as much as I expected.
To further understand, I wrote this basic example:
import numpy as np
from numba import njit, prange, float64
@njit(float64[:] (float64[:], float64[:]), parallel=True)
def array_sum(array0, array1):
"""
Sum elements of array0 to array1, similar to doing + on two numpy arrays
"""
result = np.empty(array0.shape)
for i in prange(array0.shape[0]):
result[i] = array0[i] + array1[i]
return result
And then tested with:
import time
v0 = np.random.random(10**7) # 10 million floats
v1 = np.random.random(10**7) # 10 million floats
array_sum(v0,v1) # run this once so the code compiles
#--- test start ---#
start_time = time.time()
array_sum(v0,v1) # do the work
end_time = time.time()
delta = end_time-start_time
print (delta)
On my machine I get the following results:
# direct numpy array0+array1 ---> 0.016865015029907227
# parallel=False ---> 0.016468048095703125
# parallel=True ---> 0.010709047317504883
With parallel=False the speed I get matches numpy's, which is what I expected. And with parallel=True I got a ~1.54x speed increase, which is nice, but for a simple operation like this I was expecting a larger impact on my 8 core machine.
QUESTION
Can parallelism be used in a more effective way to do vectorized operations similar to the example above?