Nun diese Art von interessantem Detail ist, wenn Sie die folgenden Befehle ausführen:
import numpy
from multiprocessing import Pool
a = numpy.arange(1000000)
pool = Pool(processes = 5)
result = pool.map(numpy.sin, a)
UnpicklingError: NEWOBJ class argument has NULL tp_new
erwarten nicht, dass so was geht, gut:
>>> help(numpy.sin)
Help on ufunc object:
sin = class ufunc(__builtin__.object)
| Functions that operate element by element on whole arrays.
|
| To see the documentation for a specific ufunc, use np.info(). For
| example, np.info(np.sin). Because ufuncs are written in C
| (for speed) and linked into Python with NumPy's ufunc facility,
| Python's help() function finds this page whenever help() is called
| on a ufunc.
yep numpy.sin wird in c als solche implementiert man nicht wirklich direkt mit Multiprocessing verwenden können.
so müssen wir es mit einer anderen Funktion wickeln
perf:
import time
import numpy
from multiprocessing import Pool
def numpy_sin(value):
return numpy.sin(value)
a = numpy.arange(1000000)
pool = Pool(processes = 5)
start = time.time()
result = numpy.sin(a)
end = time.time()
print 'Singled threaded %f' % (end - start)
start = time.time()
result = pool.map(numpy_sin, a)
pool.close()
pool.join()
end = time.time()
print 'Multithreaded %f' % (end - start)
$ python perf.py
Singled threaded 0.032201
Multithreaded 10.550432
wow, hatte nicht erwartet, dass entweder, auch ein paar Fragen für den Anfang Theres wir eine Python-Funktion auch verwenden Wenn es nur ein Wrapper gegen eine reine c-Funktion ist und auch der Aufwand für das Kopieren der Werte ist, teilt Multiprocessing standardmäßig keine Daten, so dass jeder Wert kopiert werden muss.
Sie beachten Sie, dass bei ordnungsgemäßem Segment unserer Daten:
import time
import numpy
from multiprocessing import Pool
def numpy_sin(value):
return numpy.sin(value)
a = [numpy.arange(100000) for _ in xrange(10)]
pool = Pool(processes = 5)
start = time.time()
result = numpy.sin(a)
end = time.time()
print 'Singled threaded %f' % (end - start)
start = time.time()
result = pool.map(numpy_sin, a)
pool.close()
pool.join()
end = time.time()
print 'Multithreaded %f' % (end - start)
$ python perf.py
Singled threaded 0.150192
Multithreaded 0.055083
Also, was können wir daraus nehmen, Multiprozessing groß ist, aber wir sollten immer testen und vergleichen sie ihre manchmal schneller und manchmal seine langsamer, je nachdem, wie sein verwendet ...
Zugegeben, Sie verwenden nicht numpy.sin
, aber eine andere Funktion würde ich Ihnen empfehlen zuerst zu überprüfen, dass in der Tat Multiprocessing die Berechnung beschleunigen wird, möglicherweise der Overhead des Kopierens von Werten zurück/her Sie beeinflussen kann.
So oder so ich auch glaube, dass pool.map
ist die beste, sicherste Methode des Multithreading-Code ...
Ich hoffe, das hilft.
Wenn Sie 'pool.map()' verwenden, sollten Sie 'math.sin' verwenden, da es schneller ist als' numpy.sin'. Referenz: http://stackoverflow.com/questions/3650194/are-numpys-math-functions-faster-than-pythons. – EOL
Für 'numpy.sin' sagt das [offizielle numpy/scipy Wiki] (http://wiki.scipy.org/ParallelProgramming), dass es parallel funktionieren sollte, wenn Sie [compiliere numpy mit openmp aktiviert haben] (https: // software.intel.com/de-de/articles/numpyscipy-with-intel-mkl). – ziyuang
Sie könnten auch [Bohrium] (http://bohrium.readthedocs.io/) verwenden: Es sollte so einfach sein, wie Ihre erste Zeile mit 'import bohrium als numpy' zu ersetzen ... – j08lue