Je m'excuse au préalable pour le format de blog de ma réponse. Je ne pouvais pas m'empêcher de faire un petit aperçu du monde de l'informatique parallèle.
Vous pouvez classer les modèles de programmation parallèle en deux catégories: les modèles de flux de contrôle et de flux de données.
Les modèles de flux de contrôle tentent de faire fonctionner le parallélisme dans le contexte d'un programme de contrôle explicite, essentiellement tous les ordinateurs programmables d'aujourd'hui. Le problème fondamental abordé est qu'une telle «architecture Von Neumann» n'a pas été conçue pour une exécution parallèle, mais pour des calculs séquentiels efficaces. Le parallélisme dans un tel contexte est obtenu en dupliquant des parties des modules de base (mémoire, contrôle, arithmétique).
Dupliquer uniquement l'arithmétique vous donne des instructions SIMD, toutes les ALU partagent le même compteur de programmes (PC) et exécutent donc toujours la même opération en parallèle, bien que sur des données différentes.
Dupliquer ALU et le PC mais garder le séquenceur d'instructions à l'intérieur de l'unité de contrôle vous donne une exécution Out of Order (OoO) qui produit un certain parallélisme de pipeline. Dans cette catégorie, vous avez également le très long mot d'instruction (VLWI) et les techniques de prédiction de branche. Cependant, vous voyez rarement cette catégorie au niveau logiciel.
Aller un peu plus loin consiste à dupliquer l'ensemble du `` cœur '' mais en gardant la mémoire partagée, ce sont les processeurs multicœurs actuels qui vous donnent le parallélisme des tâches (ou des threads). Partager la mémoire dans ce contexte vous pose des problèmes de concurrence très, très difficiles et subtils . Les calculs parallèles sur le multicœur actuel tournent donc complètement autour des problèmes de synchronisation / concurrence, de l'équilibre soigneux des performances (pas de synchronisation) et de la sémantique souhaitée (sémantique d'exécution séquentielle totalement synchronisée). Des exemples de cela est la PRAM ou plus populaire de nos jours le Cilk ofshoots tels que fork / join ( IntelTBB , Java.Utils.Concurrency). Les modèles CSP et Actor sont des modèles de concurrence, mais comme mentionné ci-dessus, la concurrence et le parallélisme deviennent flous dans un environnement de mémoire partagée. Le parallélisme nb est pour les performances, la concurrence pour maintenir une sémantique correcte.
La duplication de mémoire vous donne également des ordinateurs en réseau qui sont programmés avec MPI et ses semblables ou tout simplement d'étranges architectures non Von Neumann telles que les processeurs de réseau sur puce (processeur cloud, Transputer, Tilera). Les modèles de mémoire tels que UMA ou NUMA tentent de maintenir l'illusion de la mémoire partagée et peuvent exister au niveau logiciel ou matériel. MPI maintient le parallélisme au niveau du programme et ne communique que via le passage de messages. Le passage de messages est également utilisé au niveau matériel pour la communication et la concurrence (Transputer).
La deuxième catégorie est constituée des modèles de flux de données . Celles-ci ont été conçues à l'aube de l'ère informatique comme un moyen d'écrire et d'exécuter des calculs parallèles, en évitant la conception de Von Neumann. Ceux-ci sont tombés en vogue (pour le calcul parallèle) dans les années 80 après une augmentation exponentielle des performances séquentielles. Cependant, de nombreux systèmes de programmation parallèle tels que Google MapReduce, Dryad de Microsoft ou Collections simultanées d'Intel sont en fait des modèles de calcul de flux de données. À un certain point, ils représentent les calculs sous forme de graphique et l'utilisent pour guider l'exécution.
En spécifiant des parties des modèles, vous obtenez différentes catégories et sémantiques pour le modèle de flux de données. À quoi restreignez-vous la forme du graphique: DAG (CnC, Dryade), arbre (mapreduce), digraphe? Existe-t-il une sémantique de synchronisation stricte ( Lustre, programmation réactive]? Désactivez-vous la récursivité pour pouvoir avoir un calendrier statique (StreaMIT) ou offrez-vous une puissance plus expressive en ayant un planificateur dynamique (Intel CnC)? Y a-t-il une limite sur le nombre de fronts entrants ou sortants? La sémantique de déclenchement permet-elle de déclencher le nœud lorsqu'un sous-ensemble des données entrantes est disponible? Sont des flux de données de bords (traitement de flux) ou des jetons de données uniques (affectation unique statique / dynamique). Pour les travaux connexes, vous pouvez commencer par regarder les travaux de recherche sur le flux de données de personnes comme Arvind, K. Kavi, j. Sharp, W. Ackerman, R. Jagannathan, etc.
Edit: Par souci d'exhaustivité. Je dois souligner qu'il existe également des modèles parallèles axés sur la réduction et sur les modèles. Pour les stratégies de réduction, vous avez généralement une réduction de graphique et une réduction de chaîne. Haskell utilise essentiellement la réduction de graphes, qui est une stratégie très efficace sur un système séquentiel à mémoire partagée. Les doublons de réduction de chaîne fonctionnent, mais ont une propriété de mémoire privée qui la rend mieux adaptée pour être implicitement parallélisée. Les modèles basés sur des modèles sont les langages logiques parallèles, tels que le prologue simultané. Le modèle Actor est également un modèle basé sur des modèles, mais avec des caractéristiques de mémoire privée.
PS. J'utilise le terme «modèle» au sens large, couvrant les machines abstraites à des fins formelles et de programmation.