Hello,<div>I&#39;m parallelizing some code I&#39;ve written using the built in multiprocessing module. In my application, I need to multiply many large arrays together and sum the resulting product arrays (inner products). I noticed that when I parallelized this with myPool.map(...) with 8 processes (on an 8-core machine), the code was actually about an order of magnitude slower. I realized that this only happens when I use the numpy array multiplication. I defined my own array multiplication and summation. As expected, this is much slower than the numpy versions, but when I parallelized it I saw the roughly 8x speedup I expected. So something about numpy array multiplication prevented me from speeding it up with multiprocessing.</div>

<div><br></div><div>Is there a way to speed up numpy array multiplication with multiprocessing? I noticed that numpy&#39;s SVD uses all of the available cores on its own, does numpy array multiplication do something similar already?</div>

<div><br></div><div>I&#39;m copying the code which can reproduce and summarize these results. Simply run: &quot;python shared_mem.py&quot; with myutil.py in the same directory.</div><div><br></div><div>Thanks,</div><div>
Brandt</div>
<div><br></div><div><br></div><div>-- myutil.py --</div><div><br></div><div><div># Utility functions</div><div>import numpy as N</div><div>def numpy_inner_product(snap1,snap2):</div><div>    &quot;&quot;&quot; A default inner product for n-dimensional numpy arrays &quot;&quot;&quot;</div>

<div>    return N.sum(snap1*snap2.conj())</div><div><br></div><div>def my_inner_product(a,b):</div><div>    ip = 0</div><div>    for r in range(a.shape[0]):</div><div>        for c in range(a.shape[1]):</div><div>            ip += a[r,c]*b[r,c]</div>

<div>    return ip</div><div>    </div><div>def my_random(args):</div><div>    return N.random.random(args)</div><div><br></div><div><br></div><div>def eval_func_tuple(f_args):</div><div>    &quot;&quot;&quot;Takes a tuple of a function and args, evaluates and returns result&quot;&quot;&quot;</div>

<div>    return f_args[0](*f_args[1:])</div></div><div><br></div><div><br></div><div>-- shared_mem.py --</div><div><br></div><div><div><div><br></div><div>import myutil</div><div>import numpy as N</div><div>import copy</div>

<div>import itertools</div><div>import multiprocessing</div><div>import time as T</div><div>processes = multiprocessing.cpu_count()</div><div>pool = multiprocessing.Pool(processes=processes)</div><div><br></div><div>def IPs():</div>

<div>    &quot;&quot;&quot;Find inner products of all arrays with themselves&quot;&quot;&quot;</div><div>    arraySize = (300,200)</div><div>    numArrays = 50</div><div>    arrayList = pool.map(myutil.eval_func_tuple, itertools.izip(</div>

<div>        itertools.repeat(myutil.my_random,numArrays),itertools.repeat(arraySize,numArrays)))</div><div>       </div><div>    IPs = N.zeros(numArrays)</div><div>    </div><div>    startTime = T.time()</div><div>    for arrayIndex,arrayValue in enumerate(arrayList):</div>

<div>        IPs[arrayIndex] = myutil.numpy_inner_product(arrayValue, arrayValue)</div><div>    endTime = T.time() - startTime</div><div>    print &#39;No shared memory, numpy array multiplication took&#39;,endTime,&#39;seconds&#39;</div>

<div>    </div><div>    startTime = T.time()</div><div>    innerProductList = pool.map(myutil.eval_func_tuple,</div><div>         itertools.izip(itertools.repeat(myutil.numpy_inner_product),</div><div>         arrayList, arrayList))</div>

<div>    IPs = N.array(innerProductList)</div><div>    endTime = T.time() - startTime</div><div>    print &#39;Shared memory, numpy array multiplication took&#39;,endTime,&#39;seconds&#39;</div><div><br></div><div>    startTime = T.time()</div>

<div>    for arrayIndex,arrayValue in enumerate(arrayList):</div><div>        IPs[arrayIndex] = myutil.my_inner_product(arrayValue, arrayValue)</div><div>    endTime = T.time() - startTime</div><div>    print &#39;No shared memory, my array multiplication took&#39;,endTime,&#39;seconds&#39;</div>

<div><br></div><div>    startTime = T.time()</div><div>    innerProductList = pool.map(myutil.eval_func_tuple,</div><div>         itertools.izip(itertools.repeat(myutil.my_inner_product),</div><div>         arrayList, arrayList))</div>

<div>    IPs = N.array(innerProductList)</div><div>    endTime = T.time() - startTime</div><div>    print &#39;Shared memory, my array multiplication took&#39;,endTime,&#39;seconds&#39;</div><div>    </div><div>    </div>

<div>if __name__ == &#39;__main__&#39;:</div><div>    print &#39;Using&#39;,processes,&#39;processes&#39;</div><div>    IPs()</div></div></div>