IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Utiliser le double coeur


Sujet :

Caml

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 75
    Points : 34
    Points
    34
    Par défaut Utiliser le double coeur
    Bonjour

    Comment est-il possible d'exploiter pleinement les possibilités d'un double coeur avec OCaml?
    J'ai entendu parler de programmation concurrente, en créant plusieurs processus qui, si le système d'exploitation est pas trop bête, sont dirigés chacun vers un coeur du micro-processeur, mais comment la mettre en place concrètement?

    Imaginons, j'ai une fonction de type bool -> 'a que je veux appliquer simultanément à true et false, sur deux threads différents, et je veux que dès que l'une de ces deux fonctions termine, je puisse récupérer le résultat dans le processus père pour en faire ce que je veux (et arrêter l'autre Thread qui tourne encore, j'ai besoin d'un seul résultat, peu importe d'où il vient)
    Seulement dans le module Thread ils disent que le résultat est oublié dès qu'un processus termine, et qu'il n'est pas possible non plus de le faire passer par le biais d'une exception.
    Comment faire alors?
    Faut-il obligatoirement utiliser des Unix.pipe, read, write et compagnie?

    Fractal

  2. #2
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 991
    Points
    2 991
    Par défaut
    Au plus tu pourrais doubler la vitesse en t'arrachant les cheveux pour exploiter deux coeurs. Mieux vaut apprendre à bien exploiter un seul coeur, le sujet est inépuisable et le gain potentiel est en général plus élevé. Donc

    Le double coeur c'est l'affaire du serveur (il n'a qu'à servir plus de terminaux), ou de l'utilisateur (il n'a qu'à trouver plus d'applications à lancer), ou du fondeur (il n'a qu'à augmenter la fréquence et l'IPC, ou bien diviser par 2 la consommation, au lieu de doubler le nombre de coeurs).

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 75
    Points : 34
    Points
    34
    Par défaut
    Oki, pas la peine que je m'embête avec ça alors
    (c'est juste que je trouve ça dommage de voir sur les graphiques d'utilisation du microprocesseur qu'un est à 100% et l'autre à 0% )

    Merci

    Fractal

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par SpiceGuid Voir le message
    Au plus tu pourrais doubler la vitesse en t'arrachant les cheveux pour exploiter deux coeurs. Mieux vaut apprendre à bien exploiter un seul coeur, le sujet est inépuisable et le gain potentiel est en général plus élevé.
    Le double coeur c'est l'affaire du serveur (il n'a qu'à servir plus de terminaux), ou de l'utilisateur (il n'a qu'à trouver plus d'applications à lancer), ou du fondeur (il n'a qu'à augmenter la fréquence et l'IPC, ou bien diviser par 2 la consommation, au lieu de doubler le nombre de coeurs).
    C'est bien gentil comme attitude mais c'est irréaliste à l'heure actuelle : on est parti pour une course en avant dans le nombre de coeur et non dans la fréquence de ceux-ci comme auparavant. Il est donc urgent de se poser des questions sur le parallélisme de ses futurs programmes et surtout des facilités disponibles dans les langages de programmation.
    En tant que langage fonctionnels, Haskell ou OCaml partent avec un avantage non-négligeable : leurs utilisateurs sont déjà habitués à un style majoritairement sans effet de bord qui est potentiellement beaucoup plus facile à paralléliser. Maintenant il faut se poser la question des abstractions à fournir pour rendre cet avantage facilement exploitable, ainsi que des choix structurels à faire.
    Avec GHC (Haskell), il y a déjà de très intéressantes solutions disponibles :
    • tout d'abord, GHC a un modèle de threads nm extrèmement efficace, c'est-à-dire qu'il crée autant de threads systèmes qu'il y a de coeurs et qu'il exécute dessus des threads utilisateurs ultra-légers et efficaces
    • Avec le mot clé par, on peut simplement indiquer qu'on souhaite que deux valeurs soient calculés en parallèle si possible, par exemple :
      "y `par` (x,y)" calculera x et y en parallèle et renverra (x,y).
    • Construisant sur cette base, Data.Parallel.Strategies offre une librairie de combinateur pour spécifier le parallélisme indépendamment de l'algorithme.
    • NDP ou Nested Data Parallelism propose des compréhensions de tableau en parallèle, avec un grain configurable et un certain nombre de combinateurs pratiques.
    • Du côté de la concurrence plus classique, la monade STM offre des transactions mémoires logicielles, une abstraction qui propose de remplacer les systèmes de verrous plus efficacement
    • Bien sûr les mécanismes classiques de concurrence sont là aussi


    Je connais moins la scène du côté de OCaml, j'ai entendu parler d'un regain d'intérêt dans JOCaml, et je crois qu'il y a une librairie pour les STM (pas sûr), et bien sûr il y a des threads systèmes classiques, quelqu'un pourrait s'étendre un peu plus sur le sujet ?

    --
    Jedaï

  5. #5
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Points : 1 412
    Points
    1 412
    Par défaut
    Comme Jedaï, je pense que c'est un sujet intéressant, surtout que c'est censé être un point fort des langages fonctionnels. Pour Caml, il existe OCamlP3l :
    http://ocamlp3l.inria.fr/fra.htm
    Mais je ne l'ai jamais essayé, je ne sais pas ce qu'il vaut.


    Note : pour F#, il existe des fonctionnalités très intéressantes dans le langage (à base de monades).

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Il y a aussi JoCaml, qui est plus que prometteur et intéressant.

    Pour une application relativement simple, tu peux très bien le faire en "simple" OCaml avec Unix.fork, en utilisant effectivement la communication inter-processus.
    Tu trouveras de la documentation à ce sujet dans le chapitre 18 de DA-OCaml : communication entre processus (entres autres).

    Pour un passage transparent des Threads (et non forks) à une application multi-processeur, tu peux aussi regarder du côté de la prometteuse bibliothèque coThreads.

  7. #7
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par bluestorm Voir le message
    Pour une application relativement simple, tu peux très bien le faire en "simple" OCaml avec Unix.fork, en utilisant effectivement la communication inter-processus.
    Est-ce que tu es sûr que les OS modernes (donc Windows est écarté) implantent les processus lourds de cette façon ? Je ne suis pas certain qu'ils aillent jusqu'à répartir les processus lourds sur les coeurs des processeurs, mais je n'en ai pas la certitude.

    Si je lève l'interrogation, c'est essentiellement à cause d'un problème récurrent dans l'architecture des processeurs actuels. Certains modèles n'autorisent pas l'accès simultané au cache, si il est partagé, comme le Xeon (à moins que ça ait changé), donc faire s'exécuter un processus lourd par coeur semble très difficile à mettre en place.

    Si quelqu'un qui connaît la réponse pouvait éclairer... il est le bien venu !

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 75
    Points : 34
    Points
    34
    Par défaut
    @ InOCamlWeTrust

    Sur mon ordinateur (je suis sous Linux) j'observe la chose suivante :
    Quand je lance mon programme (je n'ai pas implémenté de calcul parallèle) un des coeurs est utilisé à 100% et l'autre à 0%, et ça alterne de façon aléatoire, en moyenne toutes les 5 ou 10 secondes, le processus passe d'un coeur à l'autre.
    Par contre quand je lance mon programme deux fois simultanément (indépendemment, dans deux terminaux différents) là les deux coeurs sont utilisés à 100% sans aucune interruption, donc ils sont bien répartis chacun sur un coeur différent du processus, peut-être qu'ils échangent encore leurs places régulièrement mais en tout cas le double coeur est pleinement exploité.
    Je ne sais pas si ça répond à ta question.

    Fractal

  9. #9
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Ca répond en partie à ma question mais à la tienne aussi !

    En effet, si chaque coeur fait tourner un processus lourd, la réponse est trouvée, même si de façon partielle à cause des problèmes cités avant d'accès au cache, donc aux données (l'exécution parallèle ne garantit pas que les coeurs ne sont pas en train d'attendre de façon alternée pour lire et écrire dans la mémoire : dans ce cas, le gain en performances serait presque nul).

    Concernant ta question, tu peux déjà commencer à faire ce que tu veux avec des processus lourds (qui devraient être les seuls utilisés en principe), mais il faut que tu penses l'algorithme de sorte que les processus ne puissent pas communiquer entre eux (ou alors, à l'aide de socket locales, et non de pipes, de fifo ou d'autres trucs dans le genre). En fait, il faut voir les processus lourds UNIX historiques comme des processus sans effets de bords : c'est d'ailleurs une idée forte originelle d'UNIX qui a été oubliée avec la pratique de plus de 30 ans. Chaque processus fait son petit truc, mais sans effets de bords, et sans possibilité de récupérer une valeur. En ce sens, on se rapproche un peu de l'idée de la monade IO d'Haskell, mais je ne vais pas développer plus.

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 75
    Points : 34
    Points
    34
    Par défaut
    il faut voir les processus lourds UNIX historiques comme des processus sans effets de bords
    Mais à quoi ça sert dans ce cas?
    Pourquoi créer un processus s'il ne peut pas retourner de valeur ni faire d'effet de bord? Il faut bien qu'il retourne au moins quelque chose, sinon on sait juste quand il s'arrête, sans informations supplémentaires, donc tout son calcul est perdu, non?
    Je ne comprends pas très bien comment exploiter quelque chose qui ne renvoie rien et ne fait rien.

    Fractal

  11. #11
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Ne rien renvoyer ne veut pas dire ne rien faire. Les processus peuvent faire des effets de bords, et c'est exactement ce qui se passe en Haskell avec la monade IO : il est impossible (au unsafePerformIO près...) d'extraire une valeur hors de IO. Ici, c'est pareil : tout est fait dans le processus, et rien ne s'en échappe.

    Un exemple qui m'est arrivé la dernière fois.

    J'ai dû écrire un tout petit interpréteur qui devait exécuter en parallèle plusieurs tâches rentrées dans un script. Ici, il est tout à fait envisageable de créer, au sein de l'interpréteur, un processus lourd par tâche à exécuter, avec me processus père qui attend la fin de chaque processus avant de terminer, etc... c'est d'ailleurs ce que fait ton shell quand tu lui mets des & après les commandes.

  12. #12
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par InOCamlWeTrust Voir le message
    Concernant ta question, tu peux déjà commencer à faire ce que tu veux avec des processus lourds (qui devraient être les seuls utilisés en principe)
    Pourquoi faudrait-il se limiter aux processus lourd ??

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Concernant ta question, tu peux déjà commencer à faire ce que tu veux avec des processus lourds (qui devraient être les seuls utilisés en principe), mais il faut que tu penses l'algorithme de sorte que les processus ne puissent pas communiquer entre eux (ou alors, à l'aide de socket locales, et non de pipes, de fifo ou d'autres trucs dans le genre).
    C'est quoi le problème des pipes/fifos ? Je croyais que tant qu'on a deux processus séparés, il n'y a pas de problème.

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 75
    Points : 34
    Points
    34
    Par défaut
    Et sinon qu'est-ce qu'il se passe si par exemple je crée dans le processus père une référence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let str_ref = ref "Bonjour"
    et que je la passe en argument aux deux processus fils?
    Ils ne pourront pas communiquer par le biais de cette référence? Si un des deux modifie son contenu, que verra l'autre?

    Fractal

  15. #15
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Fractal LLG Voir le message
    Et sinon qu'est-ce qu'il se passe si par exemple je crée dans le processus père une référence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let str_ref = ref "Bonjour"
    et que je la passe en argument aux deux processus fils?
    Ils ne pourront pas communiquer par le biais de cette référence? Si un des deux modifie son contenu, que verra l'autre?

    Fractal
    Les processus n'ont pas de partage mémoire. Leur espace mémoire est totalement duppliqué. Bon, après, c'est fait intelligement, mais le résultat pour l'utilisateur est qu'il n'y a pas de partage. Si tu veux un partage de la mémoire, il faut des threads. Et c'est là que les problèmes d'accès concurents commencent à se poser.

  16. #16
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Les processus n'ont pas de partage mémoire. Leur espace mémoire est totalement duppliqué. Bon, après, c'est fait intelligement, mais le résultat pour l'utilisateur est qu'il n'y a pas de partage. Si tu veux un partage de la mémoire, il faut des threads. Et c'est là que les problèmes d'accès concurents commencent à se poser.
    pas tout à fait d'accord, il existe des moyens de gérer des espaces mémoires partagés entre divers processus... du moins cela se fait sans problème en C sous windows comme sous unix, mais pas sûr que ce soit dispo dans la libraire Unix.

    après on peut aussi se dire que le principe de la mémoire partagée n'est pas compatible avec la programmation fonctionnelle pure...

  17. #17
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    après on peut aussi se dire que le principe de la mémoire partagée n'est pas compatible avec la programmation fonctionnelle pure...
    OCaml n'est pas vraiment un langage fonctionnel "pur" de toute façon. Et que ce soit avec des threads ou de la mémoire partagée entre processus, les problèmes sont les mêmes de toute façon (sauf que les threads sont plus légers et mieux intégrés dans le langage normalement). La mémoire partagée, c'est surtout utile pour coopérer avec des programmes tiers.

    --
    Jedaï

  18. #18
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par Jedai Voir le message
    OCaml n'est pas vraiment un langage fonctionnel "pur" de toute façon.
    on est d'accord : OCaml est un langage opportuniste utilisant les paradigmes fonctionnel, impératif et objet... mais il faut bien avouer quon privilégie souvent l'approche fonctionnelle

    Citation Envoyé par Jedai Voir le message
    Et que ce soit avec des threads ou de la mémoire partagée entre processus, les problèmes sont les mêmes de toute façon (sauf que les threads sont plus légers et mieux intégrés dans le langage normalement). La mémoire partagée, c'est surtout utile pour coopérer avec des programmes tiers.
    si tu parles des exclusions mutuelles au moyen de différents procédés (zone critique, mutex & sémaphore, transaction par estampillage), je ne suis pas sûr qu'il faille absolument devoir gérer cela nous-même, après tout il existe des procédés théoriques (lambda-pi calcul, Software Transactional Memory, etc)


    http://infoscience.epfl.ch/record/101108/files/

  19. #19
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    si tu parles des exclusions mutuelles au moyen de différents procédés (zone critique, mutex & sémaphore, transaction par estampillage), je ne suis pas sûr qu'il faille absolument devoir gérer cela nous-même, après tout il existe des procédés théoriques (lambda-pi calcul, Software Transactional Memory, etc)
    Je parlais de processus avec mémoire partagée vs. threads. Tu remarqueras que j'ai déjà évoqué un certain nombre de ces mécanismes alternatifs plus haut. En tout cas, le mécanisme de mémoire partagée entre processus n'apporte rien par rapport aux threads à part un système un peu plus lourd... (Au moins, si tu travailles avec des processus sans mémoire partagée, tu évites les problèmes d'accès concurrents à la mémoire)

    La mémoire partagée a d'autres utilités, mais n'est pas vraiment intéressante pour de la coopération "interne" (lorsque tu conçois l'intégralité du programme).

    --
    Jedaï

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 13/10/2008, 02h23
  2. Comment utiliser les doubles comparateurs ?
    Par Whombat dans le forum Langage
    Réponses: 3
    Dernier message: 12/10/2007, 01h21
  3. Mysql, beaucoup de données et double coeurs
    Par Ben44 dans le forum Installation
    Réponses: 1
    Dernier message: 17/09/2007, 10h51
  4. Multitâche avec un Double coeur
    Par delire8 dans le forum Composants
    Réponses: 5
    Dernier message: 24/08/2007, 20h17
  5. Je n'arrive pas à utiliser le Double buffering
    Par Yann39 dans le forum AWT/Swing
    Réponses: 43
    Dernier message: 21/01/2007, 23h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo