Параллелизм в Python - PullRequest
       10

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

22 голосов
/ 07 июня 2010

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

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

Выбор подхода к использованию является упражнением в компромиссах.

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

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

Ответы [ 5 ]

12 голосов
/ 07 июня 2010

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

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

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

5 голосов
/ 07 июня 2010

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

3 голосов
/ 20 января 2019

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)

Itимеет ряд преимуществ по сравнению с многопроцессорным модулем:

Ray - это фреймворк, который я помогал разрабатывать.

0 голосов
/ 07 июня 2010

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

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

0 голосов
/ 07 июня 2010

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

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

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

...