Beh, questa è nota piuttosto interessante se si esegue i seguenti comandi:
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
non mi aspettavo che, così che cosa è in corso, ben:
>>> 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 è implementato in C come tale non si può davvero utilizzare direttamente con multiprocessing.
quindi dobbiamo avvolgerlo con un'altra funzione
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, non mi aspettavo che o, ben theres un paio di problemi per cominciare stiamo utilizzando una funzione di pitone anche se è solo un wrapper contro una pura funzione c, e c'è anche il sovraccarico di copiare i valori, il multiprocessing di default non condivide i dati, in quanto tale ogni valore deve essere copiato avanti/indietro.
fanno notare che, se correttamente segmento nostri dati:
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
Allora, cosa possiamo prendere da questa, multiprocessing è grande, ma ci deve sempre verificare e confrontare a volte il suo più veloce e, talvolta, la sua più lenta, a seconda di come la sua usato ...
È garantito che non si sta utilizzando numpy.sin
ma un'altra funzione che si consiglia di verificare per prima cosa che la multielaborazione acceleri il calcolo, forse il sovraccarico di copia dei valori indietro/indietro potrebbe influire sull'utente.
Ad ogni modo anche io credo che usare pool.map
è il migliore, il metodo più sicuro di codice multithreading ...
Spero che questo aiuta.
Se si utilizza 'pool.map()', si dovrebbe usare 'math.sin' perché è più veloce di' numpy.sin'. Riferimento: http://stackoverflow.com/questions/3650194/are-numpys-math-functions-faster-than-pythons. – EOL
Per 'numpy.sin', il [wiki numpy/scipy ufficiale (http://wiki.scipy.org/ParallelProgramming) dice che dovrebbe funzionare in parallelo se tu [compili numpy con openmp attivato] (https: // software.intel.com/en-us/articles/numpyscipy-with-intel-mkl). – ziyuang
Puoi anche usare [Bohrium] (http://bohrium.readthedocs.io/): Dovrebbe essere semplice come sostituire la prima linea con 'import bohrium as numpy' ... – j08lue