Параллелизация операции вектора Numy

Давайте используем, например, numpy.sin()

Следующий код вернет значение синуса для каждого значения массива a :

 import numpy a = numpy.arange( 1000000 ) result = numpy.sin( a ) 

Но моя машина имеет 32 ядра, поэтому я бы хотел их использовать. (Накладные расходы могут оказаться numpy.sin() для чего-то вроде numpy.sin() но функция, которую я действительно хочу использовать, довольно сложна, и я буду работать с огромным количеством данных.)

Это лучший (читай: самый умный или быстрый) метод:

 from multiprocessing import Pool if __name__ == '__main__': pool = Pool() result = pool.map( numpy.sin, a ) 

или есть лучший способ сделать это?

  • Сортировка массива python / повторение по столбцу
  • удалить нулевые строки 2-D numpy array
  • Python встроил «все» с генераторами
  • Преобразование std :: vector в массив NumPy без копирования данных
  • чтение «потоковых» файлов middlebury с помощью python (массив байтов и numpy)
  • как искать уникальные элементы в первом столбце многомерного массива
  • Ненужный мешгрид в 3D
  • Не удалось импортировать ctypes на сервере разработки Google-приложений
  • 3 Solutions collect form web for “Параллелизация операции вектора Numy”

    Существует лучший способ: numexpr

    Немного переформулированы с их главной страницы:

    Это многопоточная виртуальная машина, написанная на C, которая анализирует выражения, переписывает их более эффективно и компилирует их на лету в код, который приближается к оптимальной параллельной производительности для ограниченных операций с памятью и оператором.

    Например, на моем 4-ядерном компьютере оценка синуса чуть меньше, чем в 4 раза быстрее, чем numpy.

     In [1]: import numpy as np In [2]: import numexpr as ne In [3]: a = np.arange(1000000) In [4]: timeit ne.evaluate('sin(a)') 100 loops, best of 3: 15.6 ms per loop In [5]: timeit np.sin(a) 10 loops, best of 3: 54 ms per loop 

    Документация, включая поддерживаемые функции. Вам нужно будет проверить или предоставить нам дополнительную информацию, чтобы узнать, может ли ваша более сложная функция быть оценена numexpr.

    Ну, это интересная заметка, если вы выполните следующие команды:

     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. 

    yep numpy.sin реализован в c как таковой, вы не можете использовать его напрямую с многопроцессорной обработкой.

    поэтому мы должны обернуть его другой функцией

    перфорация:

     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-функции, а также накладные расходы на копирование значений, многопроцессорность по умолчанию doesn ' t делиться данными, поэтому каждая ценность должна быть скопирована обратно / вперед.

    обратите внимание, что если правильно сегментировать наши данные:

     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 – лучший, самый безопасный метод многопоточного кода …

    Надеюсь, это поможет.

    SciPy на самом деле имеет довольно хорошую запись на эту тему здесь: http://wiki.scipy.org/ParallelProgramming

    Python - лучший язык программирования в мире.