Como fazer programação paralela em Python

para C++, podemos usar o OpenMP para fazer programação paralela; no entanto, o OpenMP não irá funcionar para o Python. O que devo fazer se eu quiser paralelo algumas partes do meu programa python?

a estrutura do código pode ser considerada como:

 solve1(A)
 solve2(B)

em que solve1 e solve2 são duas funções independentes. Como executar este tipo de código em paralelo, em vez de em sequência, a fim de reduzir o tempo de execução? Espero que alguém me possa ajudar. Muito obrigado antecipadamente. Codigo riz:

def solve(Q, G, n):
    i = 0
    tol = 10 ** -4

    while i < 1000:
        inneropt, partition, x = setinner(Q, G, n)
        outeropt = setouter(Q, G, n)

        if (outeropt - inneropt) / (1 + abs(outeropt) + abs(inneropt)) < tol:
            break

        node1 = partition[0]
        node2 = partition[1]

        G = updateGraph(G, node1, node2)

        if i == 999:
            print "Maximum iteration reaches"
    print inneropt

onde o setinner e o setouter são duas funções independentes. É onde eu quero paralelo...

Author: drhagen, 2013-12-12

3 answers

Pode usar o Módulomultiprocessamento . Para este caso, eu poderia usar um conjunto de processamento:

from multiprocessing import Pool
pool = Pool()
result1 = pool.apply_async(solve1, [A])    # evaluate "solve1(A)" asynchronously
result2 = pool.apply_async(solve2, [B])    # evaluate "solve2(B)" asynchronously
answer1 = result1.get(timeout=10)
answer2 = result2.get(timeout=10)

Isto vai desovar processos que podem fazer um trabalho genérico para si. Como não passamos, vai gerar um processo para cada núcleo de CPU na sua máquina. Cada núcleo de CPU pode executar um processo simultaneamente.

Se quiser mapear uma lista para uma única função, faria isto:

args = [A, B]
results = pool.map(solve1, args)

Não use threads porque o GIL bloqueia todas as operações em objectos python.

 117
Author: Matt Williamson, 2013-12-12 16:39:19
Isto pode ser feito muito elegantemente com o Ray.

Para paralelizar o seu exemplo, teria de definir as suas funções com o decorador @ray.remote, e depois invocá-las com .remote.

import ray

ray.init()

# Define the functions.

@ray.remote
def solve1(a):
    return 1

@ray.remote
def solve2(b):
    return 2

# Start two tasks in the background.
x_id = solve1.remote(0)
y_id = solve2.remote(1)

# Block until the tasks are done and get the results.
x, y = ray.get([x_id, y_id])

Há uma série de vantagens disso sobre o módulo multiprocessamento.

    O mesmo código será executado numa máquina multicore, bem como num conjunto de máquinas. Os processos compartilham dados de forma eficiente através de memória compartilhada e cópia zero. serialização . As mensagens de erro são bem propagadas.
  1. Estas chamadas de função podem ser compostas juntas, por exemplo,

    @ray.remote
    def f(x):
        return x + 1
    
    x_id = f.remote(1)
    y_id = f.remote(x_id)
    z_id = f.remote(y_id)
    ray.get(z_id)  # returns 4
    
  2. além de invocar funções remotamente, as classes podem ser instanciadas remotamente como actores.

Note queO Ray é um quadro que tenho ajudado a desenvolver.

 6
Author: Robert Nishihara, 2018-01-10 18:37:52

O CPython usa o bloqueio global do interpretador, o que torna a programação paralela um pouco mais interessante do que o c++

Este tópico tem vários exemplos e descrições úteis do desafio:

Python Global Interpreter Lock (GIL) trabalha em sistemas multi-core usando taskset no Linux?

 3
Author: bauman.space, 2017-05-23 12:34:50