Параллелизм в Python

Каковы варианты достижения параллелизма в Python? Я хочу выполнить кучу вычислений с привязкой к ЦП для некоторых очень больших растров и распараллелить их. Исходя из опыта C, я знаком с тремя подходами к параллелизму:

  1. Процессы передачи сообщений, возможно, распределенные по кластеру, например. MPI.
  2. Явный параллелизм разделяемой памяти с использованием pthreads или fork(), pipe() и т. д. все
  3. Неявный параллелизм разделяемой памяти с использованием OpenMP.

Принятие решения о подходе к использованию — это упражнение в компромиссах.

Какие подходы доступны в Python и каковы их характеристики? Существует ли кластеризованный клон MPI? Каковы предпочтительные способы достижения параллелизма с общей памятью? Я слышал упоминания о проблемах с GIL, а также упоминания о tasklets.

Короче говоря, что мне нужно знать о различных стратегиях распараллеливания в Python, прежде чем выбирать между ними?


person fmark    schedule 07.06.2010    source источник


Ответы (5)


Как правило, вы описываете расчет с привязкой к ЦП. Это не сильная сторона Python. Ни то, ни другое исторически не является многопроцессорным.

Многопоточность в основном интерпретаторе Python управляется страшной глобальной блокировкой. Новый многопроцессорный API работает вокруг этого и дает абстракцию рабочего пула с каналами, очередями и т.п. .

Вы можете написать критически важный для производительности код на C или Cython, а в качестве связующего используйте Python.

person Will    schedule 07.06.2010

Новый (2.6) модуль multiprocessing — это то, что нужно. Он использует подпроцессы, что позволяет обойти проблему GIL. Он также абстрагирует некоторые локальные/удаленные проблемы, поэтому выбор запуска вашего кода локально или распределенного по кластеру может быть сделан позже. Документация, на которую я ссылался выше, довольно интересна, но должна стать хорошей основой для начала работы.

person Edward Dale    schedule 07.06.2010

Ray — это элегантная (и быстрая) библиотека для этого.

Самая основная стратегия распараллеливания функций Python — объявить функцию с помощью декоратора @ray.remote. Затем его можно вызывать асинхронно.

import ray
import time

# Start the Ray processes (e.g., a scheduler and shared-memory object store).
ray.init(num_cpus=8)

@ray.remote
def f():
    time.sleep(1)

# This should take one second assuming you have at least 4 cores.
ray.get([f.remote() for _ in range(4)])

Вы также можете распараллелить вычисления с отслеживанием состояния, используя актеры, опять же с помощью декоратора @ray.remote.

# This assumes you already ran 'import ray' and 'ray.init()'.

import time

@ray.remote
class Counter(object):
    def __init__(self):
        self.x = 0

    def inc(self):
        self.x += 1

    def get_counter(self):
        return self.x

# Create two actors which will operate in parallel.
counter1 = Counter.remote()
counter2 = Counter.remote()

@ray.remote
def update_counters(counter1, counter2):
    for _ in range(1000):
        time.sleep(0.25)
        counter1.inc.remote()
        counter2.inc.remote()

# Start three tasks that update the counters in the background also in parallel.
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)

# Check the counter values.
for _ in range(5):
    counter1_val = ray.get(counter1.get_counter.remote())
    counter2_val = ray.get(counter2.get_counter.remote())
    print("Counter1: {}, Counter2: {}".format(counter1_val, counter2_val))
    time.sleep(1)

Он имеет ряд преимуществ перед модулем multiprocessing:

  • Один и тот же код работает как на одной многоядерной машине, так и на большом кластере.
  • Данные эффективно распределяются между процессами на одном компьютере с помощью общая память и эффективная сериализация.
  • Вы можете распараллелить функции Python (используя задачи) и классы Python (используя акторы) .
  • Сообщения об ошибках распространяются красиво.

Ray — это фреймворк, в разработке которого я участвовал.

person Robert Nishihara    schedule 19.01.2019
comment
Примечание. На данный момент Ray не поддерживается в Windows. - person NucS; 25.02.2019

Для этого есть много пакетов, наиболее подходящим, как уже говорилось, является многопроцессорность, особенно с классом «Пул».

Аналогичный результат дает parallel python, который, кроме того, предназначен для работы с кластерами.

В любом случае, я бы сказал, используйте многопроцессорность.

person pygabriel    schedule 07.06.2010

В зависимости от того, сколько данных вам нужно обработать и сколько процессоров/машин вы собираетесь использовать, в некоторых случаях лучше написать часть на C (или Java/C#, если вы хотите использовать jython/IronPython)

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

person Mattias Nilsson    schedule 07.06.2010