Есть ли в Python инструменты, которые похожи на парфор Matlab? Я нашел эту ветку , но ей четыре года. Я подумал, что, может быть, кто-то здесь может иметь более свежий опыт
Вот пример типа вещи, которую я хотел бы распараллелить:
X = np.random.normal(size=(10, 3))
F = np.zeros((10, ))
for i in range(10):
F[i] = my_function(X[i,:])
где my_function
принимает ndarray
размер (1,3)
и возвращает скаляр.
По крайней мере, я бы хотел использовать несколько ядер одновременно - как parfor. Другими словами, предположим, что система с общей памятью с 8-16 ядрами.
python
parallel-computing
Пол Г. Константин
источник
источник
Ответы:
Joblib делает то, что вы хотите. Основной шаблон использования:
где
arg_instances
список значений, для которыхmyfun
вычисляется параллельно. Основное ограничение -myfun
это функция верхнего уровня.backend
Параметр может быть либо"threading"
или"multiprocessing"
.Вы можете передать дополнительные общие параметры в распараллеленную функцию. Тело
myfun
также может ссылаться на инициализированные глобальные переменные, значения которых будут доступны детям.Аргументы и результаты могут быть практически любыми с помощью потокового бэкэнда, но результаты должны быть сериализуемыми с многопроцессорным бэкэндом.
Dask также предлагает аналогичную функциональность. Это может быть предпочтительным, если вы работаете с основными данными или пытаетесь распараллелить более сложные вычисления.
источник
threading
страдает от узкого места в GIL, аmultiprocessing
серверная часть несет большие накладные расходы из-за сериализации всех параметров и возвращаемых значений. Смотрите этот ответ для низкоуровневых деталей параллельной обработки в Python.map
который вы можете использовать напрямую. Также, если вы используете скомпилированный mkl numpy, он будет автоматически распараллеливать векторизованные операции без каких-либо действий. Numpy в Ananconda по умолчанию включен в MKL. Хотя не существует универсального решения. У Joblib очень низкий уровень шума, и в 2015 году было меньше опций.То, что вы ищете, это Numba , которая может автоматически распараллеливать цикл for. Из их документации
источник
Не предполагая что-то особенное в
my_function
выборе,multiprocessing.Pool().map()
можно предположить распараллеливание таких простых циклов.joblib
,dask
,mpi
Вычисления илиnumba
как предложено в других ответах выглядит не приносит никакой пользы для таких случаев использования и добавлять ненужные зависимости (суммировать их избыточна). Использование многопоточности, как предложено в другом ответе, вряд ли будет хорошим решением, потому что вы должны быть тесно связаны с GIL-взаимодействием вашего кода, или ваш код должен выполнять в основном ввод / вывод.Это
numba
может быть хорошей идеей для ускорения последовательного чистого кода на Python, но я чувствую, что это выходит за рамки вопроса.Однако есть некоторые предостережения (но они не должны влиять на большинство приложений):
if __name__ == "__main__"
my_function
не должен зависеть от общих состояний, таких как общение с глобальными переменными, потому что состояния не разделяются между процессами. чистые функции (функции в математическом смысле) являются примером функций, которые не разделяют состоянияисточник
Мое впечатление от parfor заключается в том, что MATLAB инкапсулирует детали реализации, поэтому он может использовать как параллелизм разделяемой памяти (что вам нужно), так и параллелизм распределенной памяти (если вы используете сервер распределенных вычислений MATLAB ).
Если вам нужен параллелизм разделяемой памяти, и вы выполняете какой-то параллельный цикл задач, вероятно, вам нужен пакет стандартной библиотеки многопроцессорной обработки , возможно, с хорошим внешним интерфейсом , таким как joblib , как упомянуто в посте Дуга. Стандартная библиотека не собирается уходить, и она поддерживается, поэтому она с низким уровнем риска.
Есть и другие варианты, такие как параллельный Python и возможности IPython . Беглый взгляд на Parallel Python заставляет меня думать, что это ближе к духу parfor, поскольку библиотека инкапсулирует детали для распределенного случая, но цена этого заключается в том, что вам необходимо принять их экосистему. Стоимость использования IPython аналогична; Вы должны принять IPython способ ведения дел, который может или не может стоить этого для вас.
Если вы заботитесь о распределенной памяти, я рекомендую mpi4py . Lisandro Dalcin отлично работает, а mpi4py используется в оболочках PETSc Python, поэтому я не думаю, что он скоро исчезнет. Как и многопроцессорная, это интерфейс низкого (er) уровня параллелизма, чем parfor, но тот, который может длиться некоторое время.
источник
Прежде чем искать инструмент «черного ящика», который можно использовать для параллельного выполнения «общих» функций Python, я бы предложил проанализировать, как
my_function()
можно распараллеливать вручную.Во-первых, сравните время выполнения
my_function(v)
сfor
накладными расходами цикла Python : [C]for
Циклы Python довольно медленные, поэтому затраченное времяmy_function()
может быть незначительным.Вторая проверка, если есть простая векторная реализация
my_function(v)
, которая не требует циклов:F[:] = my_vector_function(X)
(Эти два первых пункта довольно тривиальны, простите, если я упомянул их здесь только для полноты.)
В- третьих , и самое главное, по крайней мере , для реализации CPython, чтобы проверить , является ли
my_function
проводит большую часть времени , это внутри или снаружи от глобальной блокировки интерпретатора или GIL . Если время проводится за пределами GIL, то следует использоватьthreading
стандартный библиотечный модуль . ( Вот пример). Кстати, можно было бы написатьmy_function()
как расширение C просто для выпуска GIL.Наконец, если
my_function()
не выпустить GIL, можно использоватьmultiprocessing
модуль .Ссылки: документы Python по параллельному выполнению и введение numpy / scipy при параллельной обработке .
источник
Вы можете попробовать Юлю. Он довольно близок к Python и имеет множество конструкций MATLAB. Перевод здесь:
Это также делает случайные числа параллельными и просто объединяет результаты в конце во время сокращения. При этом используется многопроцессорная обработка (поэтому вам необходимо
addprocs(N)
добавить процессы перед использованием, и это также работает на нескольких узлах HPC, как показано в этом сообщении в блоге ).Вы также можете использовать
pmap
вместо:Если вам нужен параллелизм потоков, вы можете использовать его
Threads.@threads
(хотя убедитесь, что вы делаете алгоритм потокобезопасным). Перед открытием Джулии установите переменную среды JULIA_NUM_THREADS, а затем:Здесь я делаю отдельный массив для каждого потока, чтобы они не конфликтовали при добавлении в массив, а затем просто объединяли массивы. Потоки довольно новы, так что прямо сейчас есть только прямое использование потоков, но я уверен, что многопоточные сокращения будут добавлены в потоки и карты.
источник
я рекомендую использовать параллельные и отложенные функции библиотеки joblib, использовать модуль «tempfile» для создания временной разделяемой памяти для больших массивов, примеры и использование которых можно найти здесь https://pythonhosted.org/joblib/parallel.html
источник