Différence entre la programmation parallèle et simultanée?

44

Lorsqu'on examine la programmation simultanée, deux termes sont couramment utilisés, à savoir simultané et parallèle.

Et certains langages de programmation réclament spécifiquement le support de la programmation parallèle, tels que Java .

Cela signifie-t-il que la programmation parallèle et la programmation simultanée sont réellement différentes?

nish1013
la source
10
Oui, la programmation simultanée et parallèle est différente. Par exemple, vous pouvez avoir deux threads (ou processus) s'exécutant simultanément sur le même noyau via la commutation de contexte. Lorsque les deux threads (ou processus) sont exécutés sur deux cœurs (ou processeurs) différents, vous obtenez un parallélisme. Ainsi, dans le premier cas (concurrence), le parallélisme n’est que "virtuel", alors que dans le second, vous avez un vrai parallélisme. Par conséquent, tous les programmes parallèles sont concurrents, mais l'inverse n'est pas nécessairement vrai.
Massimo Cafaro
1
Soyez prudent ici. Vous pouvez obtenir le même résultat soit en prenant en charge une langue (par exemple, en étendant une langue avec de nouvelles constructions) ou en utilisant une approche de bas niveau (par exemple, en utilisant une bibliothèque, comme dans le cas de MPI et OpenMP). Quoi qu’il en soit, avec les processeurs multicœurs et les systèmes d’exploitation actuels prenant en charge SMP, un programme qui sera simultané s’il est exécuté sur de vieux processeurs monocœur, peut être exécuté en parallèle si le système d’exploitation planifie les tâches d’exécution du programme sur différents cœurs. La distinction est donc un peu "floue" de nos jours.
Massimo Cafaro
3
Ce que vous utilisez pour une vitesse de latence de la lumière constante. En simultanéité, vous prétendez que la vitesse de latence de la lumière est d'un cycle d'horloge. En parallèle, vous supposez qu'un serveur est voisin, tandis que dans Distributed, vous supposez qu'un serveur est sur Mars.
1
Robert Harper aborde la question dans deux articles de blog, "Le parallélisme n’est pas de la concurrence" et "Parallélisme et concurrence, revisité" , que vous voudrez peut-être vérifier.
Basil

Réponses:

26

Distinguer le parallélisme (utiliser des unités de calcul supplémentaires pour effectuer plus de travail par unité de temps) de la concurrence (gestion de l'accès aux ressources partagées). Enseignez d’abord le parallélisme car il est plus facile et aide à établir un état d’esprit non séquentiel.

Extrait de "Une sophomorique ∗ Introduction au parallélisme et à la concomitance de la mémoire partagée" de Dan Grossman (version du 16 novembre 2013)

Raphaël
la source
21

En plus de la réponse de Nish, permettez-moi de recommander le livre de Simon Marlow sur la programmation parallèle et simultanée en Haskell ou son tutoriel plus court . Ils répondent à votre première question du point de vue de Haskell, de sorte qu'ils conviendraient mieux aux lecteurs théoriquement enclins (Haskell est un langage de programmation purement fonctionnel et paresseux, beaucoup plus proche des mathématiques que d'autres langages).

Citant à partir de là:

Dans de nombreux domaines, les mots parallèle et concurrent sont des synonymes; Ce n’est pas le cas dans la programmation, où ils sont utilisés pour décrire des concepts fondamentalement différents.

Un programme parallèle est un programme qui utilise une multiplicité de matériel informatique (par exemple, plusieurs cœurs de processeur) afin d'effectuer le calcul plus rapidement. Différentes parties du calcul sont déléguées à différents processeurs qui s'exécutent en même temps (en parallèle), de sorte que les résultats peuvent être fournis plus tôt que si le calcul avait été effectué de manière séquentielle.

En revanche, la simultanéité est une technique de structuration de programme dans laquelle il existe plusieurs threads de contrôle. Notionnellement, les threads de contrôle s'exécutent "en même temps"; c'est-à-dire que l'utilisateur voit leurs effets entrelacés. Qu'ils s'exécutent en même temps ou non en même temps est un détail d'implémentation; un programme simultané peut être exécuté sur un seul processeur via une exécution entrelacée ou sur plusieurs processeurs physiques.

Je recommande de lire la suite du didacticiel (p.4), mais permettez-moi de citer une partie du reste de cette section, car elle relie les paradigmes de programmation aux caractéristiques quantitatives et qualitatives des programmes, telles que l'efficacité, la modularité et le déterminisme.

Alors que la programmation parallèle ne concerne que l'efficacité, la programmation simultanée concerne la structuration d'un programme devant interagir avec plusieurs agents externes indépendants (par exemple l'utilisateur, un serveur de base de données et certains clients externes). La simultanéité permet à de tels programmes d'être modulaires; le thread qui interagit avec l'utilisateur est distinct du thread qui communique avec la base de données. En l'absence de simultanéité, de tels programmes doivent être écrits avec des boucles d'événement et des rappels - en fait, les boucles d'événement et les rappels sont souvent utilisés même lorsque l'accès simultané est disponible, car dans de nombreuses langues, la concurrence est trop coûteuse ou trop difficile à utilisation.

La notion de "fils de contrôle" n'a pas de sens dans un programme purement fonctionnel, car il n'y a pas d'effets à observer, et l'ordre d'évaluation est sans importance. Donc, la simultanéité est une technique de structuration pour un code efficace; en Haskell, cela signifie code dans la monade IO.

Une distinction est établie entre les modèles de programmation déterministes et non déterministes. Un modèle de programmation déterministe est un modèle dans lequel chaque programme ne peut donner qu'un seul résultat, tandis qu'un modèle de programmation non déterministe admet des programmes pouvant avoir des résultats différents, en fonction de certains aspects de l'exécution. Les modèles de programmation simultanés sont nécessairement non déterministes, car ils doivent interagir avec des agents externes qui provoquent des événements à des moments imprévisibles. Le non-déterminisme présente toutefois certains inconvénients notables: les programmes deviennent de plus en plus difficiles à tester et à raisonner.

Pour la programmation parallèle, nous souhaitons utiliser autant que possible des modèles de programmation déterministes. Puisque l'objectif est simplement d'arriver à la réponse plus rapidement, nous préférons ne pas rendre notre programme plus difficile à déboguer au cours du processus. La programmation parallèle déterministe est le meilleur des deux mondes: les tests, le débogage et le raisonnement peuvent être effectués sur le programme séquentiel, mais le programme s'exécute plus rapidement lorsque des processeurs sont ajoutés. En effet, la plupart des processeurs informatiques eux-mêmes implémentent un parallélisme déterministe sous la forme d'un pipeline et de plusieurs unités d'exécution.

Bien qu'il soit possible de faire de la programmation parallèle en utilisant la simultanéité, c'est souvent un mauvais choix, car la concurrence sacrifie le déterminisme. En Haskell, les modèles de programmation parallèle sont déterministes. Cependant, il est important de noter que les modèles de programmation déterministes ne suffisent pas pour exprimer toutes sortes d'algorithmes parallèles; il existe des algorithmes qui dépendent du non-déterminisme interne, en particulier des problèmes impliquant la recherche d'un espace de solution. En Haskell, cette classe d’algorithmes ne peut être exprimée qu’en concurrence.

Nickie
la source
20

La simultanéité et le parallélisme diffèrent par les problèmes qu’ils résolvent et posent, mais ils ne sont pas indépendants.

Simultanéité

L'exécution simultanée de deux tâches signifie que les étapes individuelles des deux tâches sont exécutées de manière entrelacée. Si vous ne tenez pas compte du parallélisme, vous pouvez supposer qu’une seule instruction est exécutée à un moment donné, mais vous n’aurez (a priori) aucune garantie quant à la tâche qui exécutera l’étape suivante.

Ceci est utile à certains égards:

  • Programmation plus claire des tâches indépendantes dans un programme.
  • Permet de traiter les entrées / sorties en calculant (par exemple dans une interface graphique).
  • Permet l'exécution de plusieurs programmes à la fois (accès simultané au niveau du système d'exploitation).

Certains des principaux défis sont:

  • Maintenir la cohérence des données.
  • Évitez les impasses et les vivres .
  • Déterminez la sémantique précise des processus concurrents.
  • Déterminez les propriétés statiques qui garantissent l'exactitude.

Parallélisme

L'exécution de deux tâches en parallèle signifie que les instructions sont exécutées en même temps . Ceci est principalement utile pour:

  • Améliorez le débit du système en exécutant des programmes en parallèle (par exemple, sur des systèmes multicœurs).
  • Améliorez l'exécution de programmes individuels en utilisant plusieurs processeurs à la fois.
  • Utilisez les E / S sur de nombreuses machines (par exemple, des bases de données distribuées).

Les principaux défis incluent:

  • Problèmes de partition permettant et développant des algorithmes pouvant utiliser le parallélisme.
  • Minimiser les dépendances et la communication entre les unités de calcul.
  • Tous les problèmes posés par la simultanéité: du moins du point de vue de la mémoire, les programmes parallèles ressemblent à des problèmes concurrents du fait de la sérialisation des accès mémoire.
  • Traiter avec un support matériel sous-optimal.

Voir aussi cette question pour distinguer l'informatique parallèle et l'informatique distribuée.

Raphaël
la source
5

Une réponse légèrement idéalisée, peut-être ...

  • La simultanéité est une propriété de la façon dont un programme est écrit . Si un programme est écrit à l'aide de constructions telles que des forks / join, des verrous, des transactions, des opérations de comparaison et d'échange atomiques, etc., il est simultané.

  • Le parallélisme est une propriété de la façon dont un programme s'exécute . Si un programme s'exécute sur plusieurs unités de calcul simultanément, il s'exécute en parallèle.

John Wickerson
la source
1

Il existe une foule de réponses à ce sujet, mais cela peut être déroutant. J'aime penser de cette façon, et peut-être que ça aide ?:

La programmation concurrente est un code qui ne se soucie pas de l'ordre d'exécution. Java est un langage médiocre pour la programmation simultanée, mais il existe des bibliothèques et des frameworks pour vous aider. JavaScript est un excellent langage pour la programmation concurrente, et il est souvent difficile de vouloir écrire quelque chose qui n’est pas simultané (par exemple, si vous voulez forcer l’ordre d’exécution). La programmation simultanée est idéale pour la programmation événementielle (l'ordre d'exécution étant déterminé par les écouteurs d'événements, comme le code exécuté dans votre navigateur qui agit lorsque vous cliquez sur un bouton ou tapez dans une zone).

Un exemple pourrait inclure la création d'une centaine de requêtes HTTP. Dans NodeJS, la solution la plus simple consiste à ouvrir toutes les 100 demandes en même temps avec une méthode de rappel. Lorsque les réponses sont renvoyées, une méthode est exécutée à chaque fois. C'est la programmation concurrente. Dans Ruby, la solution la plus simple (la plus courante) consiste à ouvrir une demande et à gérer la réponse, à ouvrir la demande suivante et à gérer la réponse, etc. Pour de nombreuses demandes, NodeJS est plus facile à effectuer de Veillez à éviter de taper sur le serveur ou de maximiser vos connexions sortantes (facile à faire par erreur). Vous pouvez écrire le Ruby de manière concurrente, mais ce n'est pas la façon dont la plupart du code Ruby est écrit, et cela fait un peu mal de le faire.

Programmation parallèleCe code peut être exécuté simultanément dans plusieurs threads ou processus. Cela vous permet d'optimiser les performances en exécutant le code sur plusieurs processeurs (y compris souvent plusieurs machines, comme avec Akka). Parce que NodeJS n'est pas multi-thread et qu'il n'y a pas d'exécution parallèle, vous n'avez pas à vous soucier d'écrire du code threadsafe (et la plupart du code JavaScript que j'ai vu n'est pas threadsafe). En Java, même si le langage ne fait pas de la programmation simultanée le modèle normal, la programmation parallèle est très intégrée et vous devez souvent vous soucier de la sécurité des threads. Si vous écrivez un site Web en Java, celui-ci sera généralement exécuté dans un conteneur qui exécute chaque demande dans un thread distinct de la même mémoire.


Certains des éléments ci-dessus dépendent de la portée et des limites dont vous parlez. Je travaille sur des sites Web. La plupart du code Java que je vois n'est pas une programmation concurrente. Bien sûr, si vous effectuez un zoom arrière suffisant, l'ordre dans lequel les demandes du client sont entrées n'a pas d'importance, mais si vous effectuez un zoom avant, l'ordre d'exécution des tâches est dicté par le code. Mais le code est écrit pour que les requêtes puissent s'exécuter en parallèle avec de nombreux objets partagés devant être thread-safe.

Entre-temps, la plupart du code JavaScript que je vois est concurrent: il est écrit de manière à ce que l'ordre d'exécution soit sans importance à plusieurs niveaux. Mais il n'est pas écrit pour prendre en charge l'exécution parallèle dans la mémoire partagée. Bien sûr, vous pouvez exécuter le même code en parallèle sur plusieurs processus, mais les objets ne sont pas partagés. Il ne s'agit donc pas d'une programmation parallèle significative.

Pour des lectures supplémentaires, j'aime beaucoup les illustrations dans la réponse du haut à cette question ici: https://www.quora.com/What-are-the-differences-between-parallel-concurrent-and-asynchronous-programming

Jun-Dai Bates-Kobashigawa
la source