Что ж, это интересное замечание, если вы запустите следующие команды:
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
не ожидал этого, так что происходит, ну:
>>> 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.
да, numpy.sin реализован в c, поэтому вы не можете использовать его напрямую с многопроцессорной обработкой.
поэтому нам нужно обернуть его другой функцией
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
вау, не ожидал, что тоже, ну, есть пара проблем для начинающих, мы используем функцию python, даже если это просто оболочка против чистой функции c, и есть также накладные расходы на копирование значений, многопроцессорная обработка по умолчанию не • обмениваться данными, поэтому каждое значение необходимо копировать взад / вперед.
обратите внимание, что если правильно сегментировать наши данные:
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
Итак, что мы можем извлечь из этого, многопроцессорность - это здорово, но мы всегда должны тестировать и сравнивать ее, иногда быстрее, а иногда медленнее, в зависимости от того, как ее использовать ...
Конечно, вы не используете numpy.sin
, а другую функцию, которую я бы порекомендовал вам сначала проверить, действительно ли многопроцессорность ускоряет вычисления, возможно, накладные расходы на копирование значений назад / вперед могут повлиять на вас.
В любом случае я также верю, что использование pool.map
- лучший и самый безопасный метод многопоточного кода ...
Надеюсь, это поможет.
person
Samy Vilar
schedule
11.07.2012
pool.map()
, вам следует использоватьmath.sin
, потому что он быстрее, чемnumpy.sin
. Ссылка: stackoverflow.com/questions / 3650194 /. - person Eric O Lebigot   schedule 06.01.2014numpy.sin
в официальной вики-странице numpy / scipy говорится, что он должен работать параллельно, если вы скомпилировать numpy с включенным openmp. - person ziyuang   schedule 18.02.2015