Параллельная обработка в python - PullRequest
36 голосов
/ 01 октября 2010

Какой простой код выполняет параллельную обработку в python 2.7? Все примеры, которые я нашел в Интернете, запутаны и содержат ненужные коды.

как мне сделать простую целочисленную программу факторинга, где я могу вычислить 1 целое число на каждом ядре (4)? Моя настоящая программа, вероятно, требует только 2 ядра и должна обмениваться информацией.

Я знаю, что существуют параллельные python и другие библиотеки, но я хочу, чтобы количество используемых библиотек было минимальным, поэтому я хочу использовать библиотеки thread и / или multiprocessing, так как они поставляются с python

Ответы [ 4 ]

31 голосов
/ 02 октября 2010

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

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

from multiprocessing import Pool
import numpy

numToFactor = 976

def isFactor(x):
    result = None
    div = (numToFactor / x)
    if div*x == numToFactor:
        result = (x,div)
    return result

if __name__ == '__main__':
    pool = Pool(processes=4)
    possibleFactors = range(1,int(numpy.floor(numpy.sqrt(numToFactor)))+1)
    print 'Checking ', possibleFactors
    result = pool.map(isFactor, possibleFactors)
    cleaned = [x for x in result if not x is None]
    print 'Factors are', cleaned

Это дает мне

Checking  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
Factors are [(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
8 голосов
/ 02 октября 2010

mincemeat - это самая простая реализация из карт / редукций, которую я нашел. Кроме того, он очень легкий на зависимостях - это один файл и все делает со стандартной библиотекой.

1 голос
/ 20 июня 2014

Я согласен, что использование Pool из multiprocessing, вероятно, является наилучшим маршрутом, если вы хотите остаться в стандартной библиотеке. Если вы заинтересованы в выполнении других типов параллельной обработки, но не изучаете ничего нового (т.е. все еще используете тот же интерфейс, что и multiprocessing), то вы можете попробовать pathos, который предоставляет несколько форм параллельных карт и имеет в значительной степени тот же интерфейс, что и multiprocessing.

Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numToFactor = 976
>>> def isFactor(x):
...   result = None
...   div = (numToFactor / x)
...   if div*x == numToFactor:
...     result = (x,div)
...   return result
... 
>>> from pathos.multiprocessing import ProcessingPool as MPool
>>> p = MPool(4)
>>> possible = range(1,int(numpy.floor(numpy.sqrt(numToFactor)))+1)
>>> # standard blocking map
>>> result = [x for x in p.map(isFactor, possible) if x is not None]
>>> print result
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
>>>
>>> # asynchronous map (there's also iterative maps too)
>>> obj = p.amap(isFactor, possible)                  
>>> obj
<processing.pool.MapResult object at 0x108efc450>
>>> print [x for x in obj.get() if x is not None]
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
>>>
>>> # there's also parallel-python maps (blocking, iterative, and async) 
>>> from pathos.pp import ParallelPythonPool as PPool
>>> q = PPool(4)
>>> result = [x for x in q.map(isFactor, possible) if x is not None]
>>> print result
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]

Кроме того, pathos имеет дочерний пакет с тем же интерфейсом, который называется pyina, который запускает mpi4py, но предоставляет ему параллельные карты, которые работают в MPI и могут запускаться с использованием нескольких планировщиков.

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

>>> class Foo(object):
...   b = 1
...   def factory(self, a):
...     def _square(x):
...       return a*x**2 + self.b
...     return _square
... 
>>> f = Foo()
>>> f.b = 100
>>> g = f.factory(-1)
>>> p.map(g, range(10))
[100, 99, 96, 91, 84, 75, 64, 51, 36, 19]
>>> 

Получить код здесь: https://github.com/uqfoundation

0 голосов
/ 07 февраля 2019

Это можно сделать элегантно с Ray , системой, которая позволяет вам легко распараллеливать и распространять ваш код Python.

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

import ray

ray.init()

# Define the function to compute the factors of a number as a remote function.
# This will make sure that a call to this function will run it in a different
# process.
@ray.remote
def compute_factors(x):
    factors = [] 
    for i in range(1, x + 1):
       if x % i == 0:
           factors.append(i)
    return factors    

# List of inputs.
inputs = [67, 24, 18, 312]

# Call a copy of compute_factors() on each element in inputs.
# Each copy will be executed in a separate process.
# Note that a remote function returns a future, i.e., an
# identifier of the result, rather that the result itself.
# This enables the calls to remote function to not be blocking,
# which enables us to call many remote function in parallel. 
result_ids = [compute_factors.remote(x) for x in inputs]

# Now get the results
results = ray.get(result_ids)

# Print the results.
for i in range(len(inputs)):
    print("The factors of", inputs[i], "are", results[i]) 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...