Comment articuler la différence entre la programmation asynchrone et parallèle?


139

De nombreuses plates-formes promeuvent l'asynchronie et le parallélisme comme moyens d'améliorer la réactivité. Je comprends la différence en général, mais j'ai souvent du mal à articuler dans mon propre esprit, ainsi que pour les autres.

Je suis un programmeur de travail et j'utilise assez souvent async et callbacks. Le parallélisme semble exotique.

Mais j'ai l'impression qu'ils sont facilement confondus, en particulier au niveau de la conception du langage. J'adorerais une description claire de la façon dont ils se rapportent (ou non) et des classes de programmes où chacun est le mieux appliqué.


J'ai écrit un article de blog sur la relation entre la programmation asynchrone et parallèle - anat-async.blogspot.com/2018/08
Alexei Kaigorodov


6
le parallélisme, c'est quand les choses se produisent simultanément. L'asynchronicité se produit lorsque vous ne prenez pas la peine d'attendre que le résultat d'une action se poursuive. Vous vous endormez simplement et à un moment donné plus tard, le résultat vient, vous sonne, vous vous réveillez et continuez à partir de là. L'exécution asynchrone peut parfaitement se produire en série dans un seul thread. (c'est à peu près ce que fait javascript)
Thanasis Ioannidis

Réponses:


87

Lorsque vous exécutez quelque chose de manière asynchrone, cela signifie qu'il n'est pas bloquant, vous l'exécutez sans attendre qu'il se termine et continuez avec d'autres choses. Le parallélisme signifie exécuter plusieurs choses en même temps, en parallèle. Le parallélisme fonctionne bien lorsque vous pouvez séparer les tâches en éléments de travail indépendants.

Prenons par exemple le rendu des images d'une animation 3D. Le rendu de l'animation prend beaucoup de temps.Par conséquent, si vous lanciez ce rendu à partir de votre logiciel d'édition d'animation, vous vous assureriez qu'il s'exécute de manière asynchrone afin qu'il ne verrouille pas votre interface utilisateur et que vous puissiez continuer à faire d'autres choses. Désormais, chaque image de cette animation peut également être considérée comme une tâche individuelle. Si nous avons plusieurs processeurs / cœurs ou plusieurs machines disponibles, nous pouvons rendre plusieurs images en parallèle pour accélérer la charge de travail globale.


Voyons si je comprends ça. Les tâches parallèles de rendu des différentes images doivent être réparties sur plusieurs processeurs / cœurs. Cela n'a rien à voir avec le moment de l'achèvement de la tâche, ou si cette tâche bloque quelque chose d'autre. Cela signifie simplement qu'un tas de processeurs le feront ensemble et rendront le résultat disponible comme s'il fonctionnait sur un processeur ultra rapide. Droite?

1
"Le rendu de l'animation prend beaucoup de temps, donc si vous deviez lancer ce rendu depuis votre logiciel d'édition d'animation, vous vous assureriez (...)". Quoi?

Pour la partie animation 3D: Tout d'abord, vous n'exécuteriez JAMAIS un programme graphique 3D avec la génération d'images sur le CPU - toute personne sensée suggérerait immédiatement d'utiliser le GPU. Deuxièmement, si nous faisons cela (fortement déconseillé), nous utiliserions une minuterie pour mesurer le nombre d'images que nous pouvons rendre, sinon nous pourrions finir par construire simplement une pile de tâches d'appel de rendu inachevées. Mais votre point est parfaitement valable avec la plupart des applications de rendu 2D qui sont rendues sur une base d'événement d'entrée par utilisateur.
ワ イ き ん ぐ

1
Asynchrone et non bloquant sont des paradigmes différents .
Marquis of Lorne

73

Je pense que la principale distinction est entre la concurrence et le parallélisme .

Async et Callbacks sont généralement un moyen (outil ou mécanisme) d'exprimer la concurrence, c'est-à-dire un ensemble d'entités pouvant se parler et partager des ressources. Dans le cas d'une communication asynchrone ou de rappel, la communication est implicite alors que le partage des ressources est facultatif (considérez RMI où les résultats sont calculés sur une machine distante). Comme indiqué à juste titre, cela est généralement fait avec la réactivité à l'esprit; pour ne pas attendre de longs événements de latence .

La programmation parallèle a généralement le débit comme objectif principal tandis que la latence, c'est-à-dire le temps d'achèvement d'un seul élément, peut être pire qu'un programme séquentiel équivalent.

Pour mieux comprendre la distinction entre concurrence et parallélisme, je vais citer les modèles probabilistes de concurrence de Daniele Varacca qui sont un bon ensemble de notes pour la théorie de la concurrence:

Un modèle de calcul est un modèle de concurrence lorsqu'il est capable de représenter des systèmes comme composés de composants autonomes indépendants, communiquant éventuellement entre eux. La notion de concurrence ne doit pas être confondue avec la notion de parallélisme. Les calculs parallèles impliquent généralement un contrôle central qui répartit le travail entre plusieurs processeurs. En simultanéité, nous insistons sur l'indépendance des composants et sur le fait qu'ils communiquent entre eux. Le parallélisme est comme l'Égypte ancienne, où le pharaon décide et les esclaves travaillent. La concurrence est comme l'Italie moderne, où tout le monde fait ce qu'il veut et utilise tous les téléphones portables.

En conclusion , la programmation parallèle est quelque peu un cas particulier de concurrence où des entités distinctes collaborent pour obtenir des performances et un débit élevés (en général).

Async et Callbacks ne sont qu'un mécanisme qui permet au programmeur d'exprimer la concurrence. Considérez que les modèles de conception de programmation parallèle bien connus tels que maître / travailleur ou mapper / réduire sont mis en œuvre par des cadres qui utilisent ces mécanismes de niveau inférieur (async) pour implémenter des interactions centralisées plus complexes .


37

Cet article l'explique très bien: http://urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

Il a ceci sur la programmation asynchrone:

Les appels asynchrones sont utilisés pour empêcher le «blocage» au sein d'une application. [Un tel] appel sera spin-off dans un thread déjà existant (comme un thread d'E / S) et fera sa tâche quand il le pourra.

ceci à propos de la programmation parallèle:

Dans la programmation parallèle, vous divisez toujours le travail ou les tâches, mais la principale différence est que vous créez de nouveaux threads pour chaque morceau de travail.

et ceci en résumé:

les appels asynchrones utiliseront des threads déjà utilisés par le système et la programmation parallèle oblige le développeur à interrompre les threads de travail, de rotation et de démontage nécessaires .


3
Cet article> toutes les réponses ici (sauf celle-ci bien sûr!)
FellyTone84

1
Merci pour le lien. Donc ... en général , utilisez des appels asynchrones lors de la communication de l'interface utilisateur vers le serveur (ou d'un client vers un service Web). Utilisez des threads parallèles du côté du serveur ou du service Web, ainsi que dans votre couche de gestion.
goku_da_master

18

Ma compréhension de base est:

La programmation asynchrone résout le problème d'attendre une opération coûteuse avant de pouvoir faire autre chose. Si vous pouvez faire d'autres choses en attendant la fin de l'opération, c'est une bonne chose. Exemple: maintenir une interface utilisateur en cours d'exécution pendant que vous partez et récupérer plus de données à partir d'un service Web.

La programmation parallèle est liée mais est plus concernée par la division d'une tâche importante en petits morceaux qui peuvent être calculés en même temps. Les résultats des petits morceaux peuvent ensuite être combinés pour produire le résultat global. Exemple: lancer de rayons où la couleur des pixels individuels est essentiellement indépendante.

C'est probablement plus compliqué que cela, mais je pense que c'est la distinction fondamentale.


C'est bien dit mais c'est tout à fait faux. Tout comme l'asynchronicité, le parallélisme permet également au flux de contrôle de se poursuivre sans attendre la fin des actions. La principale différence est que le parallélisme dépend du matériel.
serkan

13

J'ai tendance à penser à la différence en ces termes:

Asynchrone: partez et faites cette tâche, lorsque vous avez terminé, revenez me dire et apportez les résultats. Je vais continuer avec d'autres choses en attendant.

Parallèle: je veux que vous fassiez cette tâche. Si cela vous facilite la tâche, demandez à des gens de vous aider. C'est urgent, alors j'attendrai ici jusqu'à ce que vous reveniez avec les résultats. Je ne peux rien faire d'autre jusqu'à ce que vous reveniez.

Bien sûr, une tâche asynchrone peut utiliser le parallélisme, mais la différenciation - du moins à mon avis - consiste à savoir si vous continuez avec d'autres choses pendant que l'opération est en cours ou si vous arrêtez tout complètement jusqu'à ce que les résultats soient obtenus.


13

async : faites-le par vous-même ailleurs et prévenez-moi lorsque vous avez terminé (rappel). Le temps que je puisse continuer à faire mon truc.

entrez la description de l'image ici

parallèle : embauchez autant de gars (threads) que vous le souhaitez et partagez le travail entre eux pour terminer plus rapidement et faites-moi savoir (rappel) lorsque vous avez terminé. Au moment où je pourrais continuer à faire mes autres choses.

entrez la description de l'image ici

la principale différence est que le parallélisme dépend principalement du matériel.


11

C'est une question d'ordre d'exécution.

Si A est asynchrone avec B, alors je ne peux pas prédire à l'avance quand les sous-parties de A se produiront par rapport aux sous-parties de B.

Si A est parallèle à B, alors les choses dans A se produisent en même temps que les choses dans B. Cependant, un ordre d'exécution peut encore être défini.

La difficulté est peut-être que le mot asynchrone est équivoque.

J'exécute une tâche asynchrone lorsque je dis à mon majordome de courir au magasin pour plus de vin et de fromage, puis de l'oublier et de travailler sur mon roman jusqu'à ce qu'il frappe à nouveau à la porte du bureau. Le parallélisme se produit ici, mais le majordome et moi sommes engagés dans des tâches fondamentalement différentes et de classes sociales différentes, donc nous n'appliquons pas cette étiquette ici.

Mon équipe de femmes de chambre travaille en parallèle lorsque chacune d'elles lave une vitre différente.

Mon équipe d'assistance aux voitures de course est parallèle de manière asynchrone en ce sens que chaque équipe travaille sur un pneu différent et qu'elle n'a pas besoin de communiquer entre elles ou de gérer des ressources partagées pendant qu'elle fait son travail.

Mon équipe de football (aka soccer) fait un travail parallèle car chaque joueur traite indépendamment les informations sur le terrain et s'y déplace, mais ils ne sont pas totalement asynchrones car ils doivent communiquer et répondre à la communication des autres.

Ma fanfare est également parallèle car chaque joueur lit la musique et contrôle son instrument, mais ils sont hautement synchrones: ils jouent et marchent dans le temps l'un vers l'autre.

Un pistolet Gatling à came pourrait être considéré comme parallèle, mais tout est 100% synchrone, donc c'est comme si un processus progressait.


9

Pourquoi asynchrone?

Les applications d'aujourd'hui étant de plus en plus connectées et potentiellement longues, les tâches ou les opérations de blocage telles que les E / S réseau ou les opérations de base de données, il est donc très important de masquer la latence de ces opérations en les démarrant en arrière-plan et en revenant à l'interface utilisateur Aussi vite que possible. Ici, l'asynchrone entre en scène, la réactivité .

Pourquoi la programmation parallèle?

Avec les ensembles de données d'aujourd'hui de plus en plus volumineux et les calculs de plus en plus complexes. Il est donc très important de réduire le temps d'exécution de ces opérations liées au processeur, dans ce cas, en divisant la charge de travail en morceaux, puis en exécutant ces morceaux simultanément. Nous pouvons appeler cela «parallèle». Évidemment, cela donnera des performances élevées à notre application.


5

Asynchrone Disons que vous êtes le point de contact pour votre client et que vous devez être réactif, c'est-à-dire que vous devez partager le statut, la complexité de l'opération, les ressources requises, etc. Vous devez maintenant effectuer une opération qui prend du temps et ne pouvez donc pas la prendre en charge car vous devez être réactif au client 24/7. Par conséquent, vous déléguez l'opération fastidieuse à quelqu'un d'autre afin de pouvoir être réactif. Ceci est asynchrone.

Programmation parallèle Supposons que vous ayez une tâche pour lire, disons, 100 lignes à partir d'un fichier texte, et que la lecture d'une ligne prend 1 seconde. Par conséquent, vous aurez besoin de 100 secondes pour lire le fichier texte. Vous craignez maintenant que le client doive attendre 100 secondes pour que l'opération se termine. Par conséquent, vous créez 9 clones supplémentaires et faites chacun d'eux lire 10 lignes du fichier texte. Maintenant, il ne faut plus que 10 secondes pour lire 100 lignes. Par conséquent, vous avez de meilleures performances.

Pour résumer, le codage asynchrone est fait pour atteindre la réactivité et la programmation parallèle est faite pour les performances.


4

Asynchrone: exécution d'une méthode ou d'une tâche en arrière-plan, sans blocage. Ne peut pas nécessairement fonctionner sur un thread séparé. Utilise la commutation de contexte / la planification du temps.

Tâches parallèles: chaque tâche s'exécute en parallèle. N'utilise pas la commutation de contexte / la planification horaire.


4

Je suis venu ici assez à l'aise avec les deux concepts, mais avec quelque chose qui ne m'est pas clair à leur sujet.

Après avoir lu certaines des réponses, je pense avoir une métaphore correcte et utile pour décrire la différence.

Si vous considérez vos différentes lignes de code comme des cartes à jouer séparées mais ordonnées (arrêtez-moi si j'explique le fonctionnement des cartes perforées à l'ancienne), alors pour chaque procédure distincte écrite, vous aurez une pile unique de cartes (ne copier-coller!) et la différence entre ce qui se passe normalement lorsque vous exécutez du code normalement et de manière asynchrone dépend de votre intérêt ou non.

Lorsque vous exécutez le code, vous remettez au système d'exploitation un ensemble d'opérations uniques (dans lesquelles votre compilateur ou interpréteur a cassé votre code de niveau «supérieur») à transmettre au processeur. Avec un seul processeur, une seule ligne de code peut être exécutée à la fois. Ainsi, afin d'accomplir l'illusion d'exécuter plusieurs processus en même temps, le système d'exploitation utilise une technique dans laquelle il n'envoie au processeur que quelques lignes d'un processus donné à la fois, basculant entre tous les processus en fonction de la façon dont il voit en forme. Le résultat est plusieurs processus montrant la progression de l'utilisateur final à ce qui semble être le même moment.

Pour notre métaphore, la relation est que le système d'exploitation mélange toujours les cartes avant de les envoyer au processeur. Si votre pile de cartes ne dépend pas d'une autre pile, vous ne remarquez pas que votre pile a cessé d'être sélectionnée tandis qu'une autre pile est devenue active. Donc, si vous vous en fichez, cela n'a pas d'importance.

Cependant, si vous vous en souciez (par exemple, il y a plusieurs processus - ou piles de cartes - qui dépendent les uns des autres), alors le brassage du système d'exploitation va bousiller vos résultats.

L'écriture de code asynchrone nécessite la gestion des dépendances entre l'ordre d'exécution, quel que soit cet ordre. C'est pourquoi des constructions comme des "rappels" sont utilisées. Ils disent au processeur, "la prochaine chose à faire est de dire à l'autre pile ce que nous avons fait". En utilisant de tels outils, vous pouvez être assuré que l'autre pile est notifiée avant d'autoriser le système d'exploitation à exécuter plus de ses instructions. ("Si called_back == false: send (no_operation)" - je ne sais pas si c'est réellement ainsi qu'il est implémenté, mais logiquement, je pense que c'est cohérent.)

Pour les processus parallèles, la différence est que vous avez deux piles qui ne se soucient pas l'une de l'autre et deux travailleurs pour les traiter. À la fin de la journée, vous devrez peut-être combiner les résultats des deux piles, ce qui serait alors une question de synchronicité mais, pour l'exécution, vous ne vous en souciez plus.

Je ne sais pas si cela aide, mais je trouve toujours plusieurs explications utiles. Notez également que l'exécution asynchrone n'est pas limitée à un ordinateur individuel et à ses processeurs. D'une manière générale, il s'agit du temps, ou (plus généralement encore) d'un ordre des événements. Donc, si vous envoyez la pile dépendante A au nœud de réseau X et sa pile couplée B à Y, le code asynchrone correct devrait être en mesure de rendre compte de la situation comme s'il s'exécutait localement sur votre ordinateur portable.


2

En règle générale, il n'y a que deux façons de faire plus d'une chose à chaque fois. L'un est asynchrone , l'autre est parallèle .

Du haut niveau, comme le serveur populaire NGINX et la célèbre bibliothèque Python Tornado , ils utilisent tous deux pleinement le paradigme asynchrone qui est un serveur à thread unique pouvant servir simultanément des milliers de clients (certains IOloop et callback ). Utilisation d' ECF (suivi des exceptions) qui pourrait implémenter le paradigme de programmation asynchrone. donc asynchrone parfois ne fait pas vraiment les choses simultanément, mais certains travaux liés à io, asynchrones pourraient vraiment améliorer les performances.

Le paradigme parallèle fait toujours référence au multi-threading et au multiprocessing. Cela peut utiliser pleinement des processeurs multicœurs, faire les choses vraiment simultanément.


-1

Résumé de toutes les réponses ci-dessus

  1. traitement en parallèle:

▪ résout le problème de débit. Préoccupé par la division d'une grande tâche en plus petits morceaux

▪ est lié à la machine (plusieurs machines / cœur / cpu / processeur nécessaires), par exemple: maître esclave, réduction de carte.

Les calculs parallèles impliquent généralement un contrôle central qui répartit le travail entre plusieurs processeurs

  1. asynchrone:

▪ résout le problème de latence, c'est-à-dire le problème «d'attendre» qu'une opération coûteuse se termine avant de pouvoir faire quoi que ce soit d'autre

▪ est lié au thread (plusieurs threads sont nécessaires)

Le threading (à l'aide de Thread, Runnable, Executor) est un moyen fondamental d'effectuer des opérations asynchrones en Java

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.