Question

Le paysage de l’architecture de la CPU a changé. La création de logiciels repose sur plusieurs cœurs. J'ai réalisé un développement multithread en C, C ++ et Java, ainsi que plusieurs processus IPC utilisant divers mécanismes IPC. Les approches traditionnelles consistant à utiliser des threads ne semblent pas permettre, pour le développeur, d’utiliser un matériel prenant en charge un degré élevé de simultanéité.

Quelles langues, bibliothèques et techniques de développement connaissez-vous qui permettent d’atténuer les problèmes traditionnels liés à la création d’applications simultanées? Je pense évidemment à des problèmes tels que les blocages et les conditions de course. Les techniques de conception, les bibliothèques, les outils, etc. sont également intéressants, car ils permettent de tirer pleinement parti des ressources disponibles et de s’assurer que celles-ci sont utilisées. Le simple fait d’écrire une application thread sécurisée et robuste ne garantit pas qu’elle utilise tous les cœurs disponibles.

Ce que j'ai vu jusqu'à présent est:

  • Erlang : processus basé sur la transmission de messages, IPC, le modèle de concurrence de l'acteur
  • Dramatis : bibliothèque de modèles d'acteurs pour Ruby et Python
  • Scala : langage de programmation fonctionnel de la machine virtuelle Java avec prise en charge ajoutée de la simultanéité
  • Clojure : langage de programmation fonctionnel de la machine virtuelle Java avec une bibliothèque d'acteurs
  • Termite : un portage de l'approche processus d'Erlang et du message transmis à Scheme

Que savez-vous d'autre, qu'est-ce qui a fonctionné pour vous et qu'est-ce qui vous semble intéressant à regarder?

Était-ce utile?

La solution

Je suggérerais deux changements de paradigme:

Mémoire transactionnelle logicielle

Vous voudrez peut-être examiner le concept de mémoire transactionnelle logicielle (STM). L’idée est d’utiliser la concurrence concurrente optimiste : toute opération exécutée en parallèle par d’autres tente de terminer son travail dans une transaction isolée; si, à un moment donné, une autre transaction validant les données sur lesquelles cette transaction fonctionne a été invalidée, le travail de la transaction est abandonné et la transaction est réexécutée.

Je pense que la première implémentation largement connue de l'idée (sinon la preuve de concept et la première) est celle de Haskell: Articles et présentations sur la mémoire transactionnelle en Haskell . De nombreuses autres implémentations sont répertoriées dans l’article sur STM de Wikipedia .

Événement en boucle et promesses

Une autre façon très différente de gérer la concurrence est mise en œuvre dans le [langage de programmation E] ( http://en.wikipedia.org/wiki/E_ (langage de programmation% 29) .

Notez que sa façon de traiter la concurrence, ainsi que d'autres parties de la conception du langage, est fortement basée sur le modèle Actor.

Autres conseils

Vous avez mentionné Java, mais vous ne mentionnez que les threads. Avez-vous examiné la bibliothèque simultanée de Java? Il est livré avec Java 5 et supérieur.

C'est une très belle bibliothèque contenant des ThreadPools, CopyOnWriteCollections, pour n'en nommer que quelques-uns. Consultez la documentation dans le didacticiel Java . Ou si vous préférez, Java docs .

J'ai utilisé le traitement pour Python. Il imite l'API du module threading et est donc très facile à utiliser.

Si vous utilisez map / imap ou une compréhension de générateur / liste, la conversion de votre code pour utiliser le traitement est simple:

def do_something(x):
    return x**(x*x)

results = [do_something(n) for n in range(10000)]

peut être mis en parallèle avec

import processing
pool = processing.Pool(processing.cpuCount())
results = pool.map(do_something, range(10000))

qui utilisera le nombre de processeurs nécessaires pour calculer les résultats. Il existe également des variantes paresseuses ( Pool.imap ) et asynchrones ( Pool.map_async ).

Il existe une classe de file d'attente qui implémente Queue.Queue et des travailleurs similaires aux threads.

Les pièges

Le traitement

est basé sur fork () , qui doit être émulé sous Windows. Les objets sont transférés via pickle / unpickle , vous devez donc vous assurer que cela fonctionne. Créer un processus qui a déjà acquis des ressources n'est peut-être pas ce que vous voulez (pensez aux connexions de base de données), mais en général cela fonctionne. Cela fonctionne tellement bien qu’il a été ajouté à Python 2.6 en accéléré (cf. PEP -317 ).

Les modules de construction du threading d'Intel pour C ++ me paraissent très intéressants. Il offre un niveau d'abstraction beaucoup plus élevé que les threads bruts. O'Reilly a un très livre sympa si vous aimez la documentation sur les arbres morts. Voir aussi Des expériences avec les blocs de construction de threading d’Intel? .

Je dirais:

Modèles: threads + état partagé, acteurs + transmission de messages, mémoire transactionnelle, mappage / réduction? Langues: Erlang, Io, Scala, Clojure, Reia Bibliothèques: Retlang, Jetlang, Kilim, Cilk ++, fork / rejoindre, MPI, Kamaelia, Terracotta

Je tiens un blog sur les liens d'accès simultané sur des sujets comme celui-ci (Erlang, Scala, threading Java, modèle d'acteur, etc.) et j'affiche quelques liens par jour:

http://concurrency.tumblr.com

Je fais de la programmation simultanée à Ada depuis près de 20 ans maintenant.

Le langage lui-même (pas une bibliothèque intégrée) prend en charge les threads ("tâches"), plusieurs modèles de planification et plusieurs paradigmes de synchronisation. Vous pouvez même créer vos propres schémas de synchronisation en utilisant les primitives intégrées.

Vous pouvez penser au rendezvous d'Ada comme une sorte de Fonction de synchronisation orientée vers les procédures, tout en protected les objets sont plus orientés objet. Les rendez-vous ressemblent à l'ancien concept CS de moniteurs , mais beaucoup plus puissants. Les objets protégés sont des types spéciaux avec des primitives de synchronisation qui vous permettent de construire des objets exactement comme des verrous de système d'exploitation, des sémaphores, des événements, etc. Cependant, il est suffisamment puissant pour que vous puissiez également inventer et créer vos propres types d'objets de synchronisation, en fonction de vos besoins. .

La question Quoi modèle de programmation parallèle recommandez-vous aujourd’hui de tirer parti des multiples processeurs de demain? a déjà été demandé. J'ai également donné la réponse suivante.

Kamaelia est un cadre python permettant de créer des applications avec beaucoup de communication. processus.

  

Kamaelia - La concurrence est utile, amusant

     

En Kamaelia, vous construisez des systèmes à partir de composants simples qui se parlent . Cela accélère le développement, facilite considérablement la maintenance et vous permet également de créer un logiciel naturellement concurrent . Il est destiné à être accessible par tous les développeurs, y compris les novices. C'est aussi amusant :)

     

Quel type de systèmes? Serveurs de réseau, clients, applications de bureau, jeux basés sur Pygame, systèmes de transcodage et pipelines, systèmes de télévision numérique, suppresseurs de spam, outils pédagogiques et bien plus encore :)

Voici une vidéo de Pycon 2009. Elle commence par comparer Kamaelia à Twisted et Parallel Python, puis donne une démonstration pratique de Kamaelia.

Accès concurrentiel facile avec Kamaelia - Partie 1 (59:08)
Accès concurrentiel facile avec Kamaelia - Partie 2 (18h15)

Je connais Reia , un langage basé sur Erlang mais qui a l'air plus comme Python / Ruby.

OpenMP .

Il gère les threads pour vous, de sorte que vous ne vous souciez que des parties de votre application C ++ que vous souhaitez exécuter en parallèle.

par exemple.

#pragma omp parallel for
for (int i=0; i < SIZE; i++) 
{
// do something with an element
}

le code ci-dessus exécutera la boucle for sur autant de threads que vous avez demandé à l'open runtime d'utiliser. Par conséquent, si SIZE est égal à 100 et que vous avez une boîte quad-core, cette boucle for exécutera 25 éléments sur chaque noyau.

Il existe quelques autres extensions parallèles pour différentes langues, mais celles qui m'intéressent le plus sont celles qui fonctionnent sur votre carte graphique. C'est un vrai traitement parallèle :) (exemples: GPU ++ et libSh )

C ++ 0x fournira des fonctions std :: lock pour verrouiller plusieurs mutex ensemble. Cela contribuera à réduire le blocage en raison d'un verrouillage en panne. De plus, la bibliothèque de threads C ++ 0x comportera des promesses, des futures et des tâches empaquetées, permettant à un thread d'attendre le résultat d'une opération effectuée sur un autre thread sans aucun verrou de niveau utilisateur.

multitraitement est une bibliothèque python qui simplifie la programmation multicœur, comme indiqué dans une autre réponse.

Le programme écrit avec le multitraitement de python peut facilement être modifié pour être envoyé sur le cloud plutôt que sur des cœurs locaux. piCloud en tire parti pour fournir une puissance de traitement importante et à la demande sur le cloud: il vous suffit de modifier 2 lignes de votre code.

Alors, voici ce qu’il faut retenir: lorsqu’on choisit une bibliothèque multi-cœur, on peut s’interroger sur l’utilité d’une approche basée sur le cloud.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top