Comment faire de la programmation parallèle en Python

pour C++, Nous pouvons utiliser OpenMP pour faire de la programmation parallèle; cependant, OpenMP ne fonctionnera pas pour Python. Que dois-je faire si je veux mettre en parallèle certaines parties de mon programme python?

la structure du code peut être considérée comme:

 solve1(A)
 solve2(B)

solve1 et solve2 sont deux fonctions indépendantes. Comment exécuter ce type de code en parallèle plutôt que dans l'ordre afin de réduire la durée d'exécution? J'espère que quelqu'un pourra m'aider. Merci beaucoup à l'avance. Le code est:

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

où setinner et setouter sont deux fonctions indépendantes. C'est là que je veux faire un parallèle...

98
demandé sur drhagen 2013-12-12 20:19:17

3 réponses

vous pouvez utiliser le module multiprocessing . Pour ce cas, je pourrais utiliser un pool de traitement:

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)

cela générera des processus qui peuvent faire du travail générique pour vous. Puisque nous n'avons pas passé processes , il va générer un processus pour chaque noyau CPU sur votre machine. Chaque noyau CPU peut exécuter un processus simultanément.

si vous voulez mapper une liste à une seule fonction, vous feriez ceci:

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

N'utilisez pas de threads car le GIL bloque toutes les opérations sur les objets python.

117
répondu Matt Williamson 2013-12-12 16:39:19

cela peut être fait très élégamment avec Ray .

Pour paralléliser votre exemple, vous devez définir vos fonctions avec le @ray.remote décorateur, puis d'appeler .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])

il existe un certain nombre d'avantages par rapport au module multiprocessing .

  1. cluster de machines.
  2. Processus de partage de données de manière efficace par le biais de la mémoire partagée et les zéro-copie de la sérialisation .
  3. Les messages D'erreur
  4. se propagent bien.
  5. ces appels de fonction peuvent être composés ensemble, p.ex.,

    @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
    
  6. en plus d'invoquer des fonctions à distance, les classes peuvent être instanciées à distance comme actors .

notez que Ray est un cadre que j'ai aidé à développer.

6
répondu Robert Nishihara 2018-01-10 18:37:52

CPython utilise L'interpréteur Global Lock qui rend la programmation parallèle un peu plus intéressante que C++

cette rubrique contient plusieurs exemples et descriptions utiles du défi:

Python Mondiale Interprète de Verrouillage (GIL) solution de contournement sur les systèmes multi-core à l'aide de taskset sur Linux?

3
répondu bauman.space 2017-05-23 12:34:50