dobrze jest to rodzaj interesująca uwaga, jeśli uruchomić następujące polecenia:
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
nie spodziewałem się, że tak Siema dzieje się, dobrze:
>>> 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 jest zaimplementowany w c, dlatego nie można go używać bezpośrednio w trybie wieloprocesorowym.
więc musimy owinąć go z innej funkcji
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, nie spodziewałem się, że obaj, dobrze tam kilka problemów na początek używamy funkcji Pythona nawet jeśli jest to tylko funkcja otoki a funkcja czystego c, a także narzut kopiowania wartości, to proces wieloprocesowy domyślnie nie współużytkuje danych, jako że każda wartość musi być kopiowana w przód/w tył.
należy pamiętać, że jeśli prawidłowo Segment nasze dane:
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
Więc co możemy z tym wieloprocesorowe jest wielki, ale zawsze powinniśmy przetestować i porównać go czasami szybszym a czasami także jej wolniej, w zależności od sposobu jej używany ...
Zgoda, że nie używasz numpy.sin
, ale inną funkcją, którą poleciłbym ci najpierw sprawdzić, czy rzeczywiście proces wieloprocesowy przyspieszy obliczenia, może narzut kopiowania wartości w przód/w tył może wpłynąć na ciebie.
Tak czy inaczej ja też nie uwierzyć, że za pomocą pool.map
jest najlepsza, najbezpieczniejsza metoda kodu wielowątkowość ...
Mam nadzieję, że to pomaga.
Jeśli zamierzasz użyć 'pool.map()', powinieneś użyć 'math.sin', ponieważ jest on szybszy niż' numpy.sin'. Odniesienia: http://stackoverflow.com/questions/3650194/are-numpys-math-functions-faster-than-pythons. – EOL
Dla 'numpy.sin', [oficjalne numpy/scipy wiki] (http://wiki.scipy.org/ParallelProgramming) mówi, że powinien działać równolegle, jeśli [kompilujesz numpy z włączonym openmp] (https: // software.intel.com/en-us/articles/numpyscipy-with-intel-mkl). – ziyuang
Można również użyć [Bohrium] (http://bohrium.readthedocs.io/): Powinno być tak proste, jak zamiana pierwszej linii na 'import bohrium jako numpy' ... – j08lue