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...
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.
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.
-
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
- 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.
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?