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 souhaite mettre en parallèle certaines parties de mon programme python?
La structure du code peut être considérée comme:
solve1(A)
solve2(B)
Où solve1
et solve2
sont deux fonctions indépendantes. Comment exécuter ce type de code en parallèle plutôt qu'en séquence afin de réduire le temps d'exécution? J'espère que quelqu'un pourra m'aider. Merci d'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 mettre en parallèle ...
python
parallel-processing
ilovecp3
la source
la source
Réponses:
Vous pouvez utiliser le module multitraitement . Dans ce cas, je pourrais utiliser un pool de traitement:
Cela engendrera des processus qui peuvent effectuer un travail générique pour vous. Comme nous n'avons pas réussi
processes
, il engendrera un processus pour chaque cœur de processeur de votre machine. Chaque cœur de processeur peut exécuter un processus simultanément.Si vous souhaitez mapper une liste à une seule fonction, procédez comme suit:
N'utilisez pas de threads car le GIL verrouille toutes les opérations sur les objets python.
la source
pool.map
n'accepte aussi les dictionnaires comme args? Ou seulement de simples listes?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 les appeler avec.remote
.Il y a un certain nombre d'avantages à cela par rapport au module multiprocesseur .
Ces appels de fonction peuvent être composés ensemble, par exemple,
Notez que Ray est un framework que j'ai aidé à développer.
la source
pip
. Je suggérerais d'essayerpip install --upgrade pip
. Si vous devez utilisersudo
du tout, il est possible que la version depip
celle que vous utilisez pour installerray
ne soit pas la même que celle qui est mise à niveau. Vous pouvez vérifier avecpip --version
. De plus, Windows n'est actuellement pas pris en charge, donc si vous êtes sous Windows, c'est probablement le problème.CPython utilise le Global Interpreter 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:
Solution de contournement Python Global Interpreter Lock (GIL) sur les systèmes multicœurs utilisant un ensemble de tâches sous Linux?
la source
La solution, comme d'autres l'ont dit, consiste à utiliser plusieurs processus. Le cadre le plus approprié dépend cependant de nombreux facteurs. En plus de ceux déjà mentionnés, il y a aussi charm4py et mpi4py (je suis le développeur de charm4py).
Il existe un moyen plus efficace d'implémenter l'exemple ci-dessus que d'utiliser l'abstraction du pool de nœuds de calcul. La boucle principale envoie les mêmes paramètres (y compris le graphique complet
G
) à plusieurs reprises aux travailleurs dans chacune des 1000 itérations. Étant donné qu'au moins un travailleur résidera sur un processus différent, cela implique de copier et d'envoyer les arguments aux autres processus. Cela peut être très coûteux selon la taille des objets. Au lieu de cela, il est logique que les travailleurs stockent l'état et envoient simplement les informations mises à jour.Par exemple, dans charm4py, cela peut être fait comme ceci:
Notez que pour cet exemple, nous n'avons vraiment besoin que d'un seul travailleur. La boucle principale pourrait exécuter l'une des fonctions et demander au travailleur d'exécuter l'autre. Mais mon code aide à illustrer plusieurs choses:
result_a.get()
attente du résultat est bloquée, le travailleur A effectue le calcul dans le même processus.la source
Dans certains cas, il est possible de paralléliser automatiquement les boucles à l'aide de Numba , bien que cela ne fonctionne qu'avec un petit sous-ensemble de Python:
Malheureusement, il semble que Numba ne fonctionne qu'avec des tableaux Numpy, mais pas avec d'autres objets Python. En théorie, il pourrait également être possible de compiler Python en C ++ , puis de le paralléliser automatiquement à l'aide du compilateur Intel C ++ , même si je n'ai pas encore essayé cela.
la source
Vous pouvez utiliser la
joblib
bibliothèque pour effectuer des calculs parallèles et des multiprocesseurs.Vous pouvez simplement créer une fonction
foo
que vous souhaitez exécuter en parallèle et basée sur le morceau de code suivant, implémenter le traitement parallèle:Où
num_cores
peut être obtenu de lamultiprocessing
bibliothèque comme suit:Si vous avez une fonction avec plus d'un argument d'entrée et que vous souhaitez simplement parcourir l'un des arguments par une liste, vous pouvez utiliser la
partial
fonction de lafunctools
bibliothèque comme suit:Vous pouvez trouver une explication complète du multitraitement python et R avec quelques exemples ici .
la source