Подтвердить что ты не робот

Parallelism в Python

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

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

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

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

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

4b9b3361

Ответ 1

Как правило, вы описываете вычисление привязки CPU. Это не Python forte. Ни исторически, ни многопроцессорно.

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

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

Ответ 2

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

Ответ 4

Существует много пакетов, наиболее подходящих, поскольку другие говорят, что это многопроцессорность, особенно с классом "Пул".

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

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

Ответ 5

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

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

Ответ 6

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

Самая основная стратегия распараллеливания функций Python - это объявление функции с @ray.remote декоратора @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)

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

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

Рэй - это основа, которую я помогал развивать.