De nombreuses plateformes 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 esprit, ainsi que pour les autres.
Je suis un programmeur de travail et j'utilise assez souvent l'async et les rappels. Le parallélisme est exotique.
Mais j'ai l'impression qu'ils sont facilement confondus, en particulier au niveau de la conception du langage. Aimerait une description claire de la façon dont ils sont liés (ou non), et des classes de programmes où chacun est le mieux appliqué.
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 des 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, donc si vous deviez lancer ce rendu à partir de votre logiciel d'édition d'animation, vous vous assureriez qu'il s'exécutait de manière asynchrone afin qu'il ne bloque 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.
Je crois que la principale distinction est entre concurrence et 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 est implicite tandis que le partage des ressources est facultatif (considérez RMI où les résultats sont calculés sur une machine distante). Comme indiqué correctement, cela se fait généralement en tenant compte de la réactivité; pour ne pas attendre longtemps latence événements.
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 pour 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 est un bon ensemble de notes pour la théorie de simultanéité:
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 simultanéité 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 soulignons l'indépendance des composants et le fait qu'ils communiquent avec les uns les autres. 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ù chacun fait ce qu'il veut et utilise tous des 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).
L'async et les rappels 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 implémentés par des cadres qui utilisent de tels mécanismes de niveau inférieur (async) pour implémenter des interactions plus complexes centralisées.
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" dans une application. [Un tel] appel se déroule dans un thread déjà existant (tel qu'un thread d'E/S) et accomplit sa tâche quand il le peut.
ceci sur la programmation parallèle:
Dans la programmation parallèle, vous divisez toujours le travail ou les tâches, mais les principales différences sont que vous faites tourner de nouveaux threads pour chaque morceau de travail
et ceci en résumé:
les appels asynchrones utiliseront les threads déjà utilisés par le système et la programmation parallèle nécessite le développeur de briser le travail, le spin-up et le démontage des threads nécessaires .
Ma compréhension de base est:
La programmation asynchrone résout le problème d'attendre qu'une opération coûteuse se termine avant de pouvoir faire quoi que ce soit d'autre. Si vous pouvez effectuer d'autres tâches en attendant la fin de l'opération, c'est une bonne chose. Exemple: maintenir une interface utilisateur en cours de route et récupérer plus de données à partir d'un service Web.
La programmation parallèle est liée mais concerne plus la division d'une tâche volumineuse en morceaux plus petits qui peuvent être calculés en même temps. Les résultats des plus 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.
J'ai tendance à penser à la différence en ces termes:
Asynchrone: partez et faites cette tâche, lorsque vous avez terminé, revenez me le 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 cependant, je vais attendre ici jusqu'à ce que vous reveniez avec les résultats. Je ne peux rien faire d'autre jusqu'à votre retour.
Bien sûr, une tâche asynchrone peut utiliser le parallélisme, mais la différenciation - à mon avis du moins - est de 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 connus.
async : faites-le par vous-même ailleurs et informez-moi lorsque vous avez terminé (rappeler). Au moment où je peux continuer à faire mon truc.
parallèle : Embauchez autant de gars (threads) que vous le souhaitez et divisez le travail à leur faire plus rapidement et faites-moi savoir (rappel) lorsque vous avez terminé. Au moment où je pourrais continuer à faire mes autres trucs.
la principale différence est que le parallélisme dépend principalement du matériel.
C'est une question d'ordre d'exécution.
Si A est asynchrone avec B, 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 toujours ê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 différentes classes sociales, donc nous n'appliquons pas cette étiquette ici.
Mon équipe de femmes de chambre travaille en parallèle lorsque chacune lave une fenêtre différente.
Mon équipe d'assistance pour les voitures de course est parallèle de manière asynchrone dans la mesure où chaque équipe travaille sur un pneu différent et n'a pas besoin de communiquer entre elles ni de gérer des ressources partagées pendant qu'elle fait son travail.
Mon équipe de football (aka football) fait un travail parallèle car chaque joueur traite indépendamment les informations sur le terrain et se déplace sur celui-ci, mais ils ne sont pas complètement 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 très synchrones: ils jouent et marchent dans le temps.
Un pistolet à came cammed pourrait être considéré comme parallèle, mais tout est 100% synchrone, c'est donc comme si un processus allait de l'avant.
Pourquoi asynchrone?
Alors que les applications d'aujourd'hui sont de plus en plus connectées et exécutent également des tâches potentiellement longues ou des 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, Réactivité .
Pourquoi la programmation parallèle?
Avec les ensembles de données d'aujourd'hui qui s'agrandissent et les calculs qui deviennent 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". De toute évidence, cela donnera de hautes performances à notre application.
Asynchrone: exécution d'une méthode ou d'une tâche en arrière-plan, sans blocage. Peut ne pas nécessairement s'exécuter sur un thread séparé. Utilise la commutation de contexte/la programmation horaire.
Tâches parallèles: chaque tâche s'exécute en parallèle. N'utilise pas de changement de contexte/planification horaire.
Je suis venu ici assez à l'aise avec les deux concepts, mais avec quelque chose qui ne m'est pas clair.
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 lignes de code individuelles 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.
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ète a cassé votre code de niveau "supérieur") à transmettre au processeur. Avec un processeur, une seule ligne de code peut être exécutée à la fois. Ainsi, afin de réaliser l'illusion de l'exécution de plusieurs processus en même temps, le système d'exploitation utilise une technique dans laquelle il envoie au processeur seulement quelques lignes d'un processus donné à la fois, en basculant entre tous les processus en fonction de la façon dont il voit en forme. Le résultat est de multiples processus montrant la progression de l'utilisateur final à ce qui semble être en même temps.
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 à partir du moment où une autre pile est devenue active. Donc, si vous ne vous en souciez pas, cela n'a pas d'importance.
Cependant, si vous vous en souciez (par exemple, il existe plusieurs processus - ou piles de cartes - qui dépendent les uns des autres), le brassage du système d'exploitation va gâcher vos résultats.
L'écriture de code asynchrone nécessite de gérer les dépendances entre l'ordre d'exécution, quel que soit l'ordre final. C'est pourquoi des constructions comme les "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 de permettre au système d'exploitation d'exécuter plus de ses instructions. ("If called_back == false: send (no_operation)" - je ne sais pas si c'est réellement la façon dont 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 pouvoir tenir compte de la situation comme s'il s'exécutait localement sur votre ordinateur portable.
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é du fonctionnement, les ressources nécessaires, etc. chaque fois que cela vous est demandé. Vous avez maintenant une opération longue à faire et vous ne pouvez donc pas la reprendre car vous devez être à l'écoute du client 24/7. Par conséquent, vous déléguez l'opération fastidieuse à quelqu'un d'autre afin que vous puissiez être réactif. C'est asynchrone.
Programmation parallèle Supposons que vous ayez une tâche à lire, disons, 100 lignes à partir d'un fichier texte, et la lecture d'une ligne prend 1 seconde. Par conséquent, vous aurez besoin de 100 secondes pour lire le fichier texte. Vous vous inquiétez 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 en sorte que chacun d'eux lise 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 effectué pour atteindre la réactivité et la programmation parallèle est effectuée pour les performances.
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 célèbre Python bibliothèque Tornado, ils ont tous deux pleinement utiliser le paradigme asynchrone qui est un serveur à thread unique pourrait servir simultanément des milliers de clients (certains IOloop et callback). Utiliser ECF (suivi du contrôle 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 favoriser les performances.
Le paradigme parallèle fait toujours référence au multithread et au multitraitement. Cela peut utiliser pleinement les processeurs multicœurs, faire les choses vraiment simultanément.