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

Programmation parallèle, calcul scientifique et de haute performance (HPC) Discussion :

[Fortran] Blocage du code avec plusieurs processus


Sujet :

Programmation parallèle, calcul scientifique et de haute performance (HPC)

  1. #1
    Membre habitué
    Homme Profil pro
    ingénieur calcul
    Inscrit en
    Décembre 2007
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 363
    Points : 180
    Points
    180
    Par défaut [Fortran] Blocage du code avec plusieurs processus
    Chers lecteurs du forum,
    j'ai déjà posé ici plusieurs questions relatives au développement que j'ai à faire à mon boulot, et vos réponses m'ont bien aidé donc je reviens. C'est un gros programme en fortran, enfin gros pour moi en tous cas, qui ne suis pas du tout développeur mais ingénieur en calcul de structures.

    [question]
    J'essaye de profiter des plusieurs processeurs que possèdent plusieurs machines en utilisant l'environnement OpenMP. (Open Multi-Processing)
    C'est une extension de compilation de gfortran que j'utilise, et qui devrait permettre de passer les calculs sur plusieurs processeurs à la fois, donc plus vite en fin de compte.
    Seulement, alors que le programme se comporte bien sur un seul processeur (donc il est à peu près propre), lorsque je lui demande d'effectuer des calculs sur 2, 4, ou 6 processeurs, il se bloque sans explication; sauf de rares fois avec deux processeurs, mais ce n'est pas reproductible, donc je ne peux même pas essayer de deviner ce qui le bloque et où.
    Le temps CPU du/des process continue d'augmenter, mais plus aucune sortie ne se fait alors que j'ai truffé le programme de sorties d'informations diverses, pour tenter de comprendre ce qu'il se passait et où on en était. Il se passe la même chose lorsque je redirige la sortie vers un fichier; celui-ci ne se remplit plus alors que le temps CPU continue d'augmenter, dans une partie du programme où les sorties devraient être nombreuses.
    Comment faire pour y comprendre quelque chose ?
    Pourquoi le temps CPU consommé augmente t'il encore alors que rien ne se passe, et comment savoir quelles sont les opérations en cours ?
    Merci,
    David

    [lecture optionnelle]
    Le programme lit ses données d'entrée, entiers et réels, dans six fichiers.
    Le premier ne contient principalement qu'une liste d'entités à traiter de façon répétitive. (jusqu’à onze mille entités environ)
    À l'aide de trois autres des fichiers d'entrée, chaque entité est transformée en une série d'une centaine de couples entier-réel.
    À l'aide de ces couples, les deux autres fichiers servent à fabriquer une gigantesque matrice de 27752 lignes par 251 colonnes, dans le sous-programme le plus gourmand en ressources-machine. (Ce que je voudrais partager, à la base)
    Puis chaque colonne est traitée pour donner finalement un simple nombre en sortie, qui est donc une fonction de l'entité sélectionnée. (et des contenus fixes des divers fichiers)
    Ça finit par faire un sacré paquet d'opérations semblables, que je voudrais partager entre les processeurs de la machine que j'ai pour ce boulot. (une linux red-hat assez balèze à seize processeurs)

    [piste possible]
    J'ai lu quelque part à propos du debugger gdb, qu'on pouvait l'utiliser sur un programme déjà en cours d'exécution; savez vous si ça pourrait m'aider et comment faire ?
    Merci encore,
    David
    P.S. Dis Toto, pourquoi l'univers existe-t'il ?
    Je vais y réfléchir avec Morphée et lui dès avant 22h55, donc ici, il faut se causer avant.

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 152
    Points : 191
    Points
    191
    Par défaut
    Bonjour,

    Ton problème ressemble à un problème soit :
    1. de synchronisation entre les différents processus
    2. de déclaration de région parallèle.

    En OpenMP, il est nécessaire de spécifier quelles sont les région parallèles d'une part, mais également le statut des variables (si une variable est partagée ou privée par exemple).
    De plus, lors des sauvegardes, il est primordial de s'assurer que chaque threads (ou processeurs pour faire simple) écrive sur une ligne distincte. Il convient donc soit :
    1. d'attribuer à chacun d'entre eux un pointeur de fichier différent,
    2. de rendre l'écriture/lecture séquentielle en s'assurant que chaque thread n'aille pas lire/écrire sur la même entrée qu'un autre thread.

    Par exemple, pour paralléliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    !Ce programme est un programme de démo
    program test
    implicit none
    real(kind=8),dimension(1000) :: tab
    real(kind=8) :: pi=acos(-1),tmp
     
    integer :: i
     
    do i=1,size(tab,1)
    tmp=real(i,8)*pi
    tab(i)=tmp
    end do
     
    open(11,file='mon_fichier',status='replace',action='write')
    do i=1,size(tab,1)
    write(11,*)tab(i)
    end do
     
    close(11)
    end program
    Ou peut utiliser l'approche suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    !Ce programme est un programme de démo
    program test
    implicit none
    real(kind=8),dimension(1000) :: tab
    real(kind=8) :: pi=acos(-1),tmp
     
    integer :: i
     
    !$OMP PARALLEL DEFAULT(NONE) SHARED(tab,pi) PRIVATE(tmp) !Déclaration de la région parallèle. Le DEFAULT(NONE) retire le statut shared par défaut sur les variables
    !$OMP DO !on parallélise la boucle sur i
    do i=1,size(tab,1)
    tmp=real(i,8)*pi
    tab(i)=tmp
    end do
    !$OMP END DO !fin de la parallélisation sur i
     
    !Attention : le fichier ne doit être ouvert que par un seul thread. Dans cet exemple, seul un seul thread écrit la valeur de la variable partagée tab
    !$OMP SINGLE
    open(11,file='mon_fichier',status='replace',action='write')
     
    do i=1,size(tab,1)
    write(11,*)tab(i)
    end do
    close(11)
    !$OMP END SINGLE !Fin du single (cette instruction inclus une synchronisation implicite)
    !$OMP END PARALLEL !Destruction de la région parallèle
     
    end program
    Dans cet exemple, on utilise qu'un seul thread pour écrire les valeurs à sauvegarder (instruction SINGLE), ce qui permet d'éviter les conflits.

    En espérant avoir répondu à ta question,

    Marlan

  3. #3
    Membre habitué
    Homme Profil pro
    ingénieur calcul
    Inscrit en
    Décembre 2007
    Messages
    363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 363
    Points : 180
    Points
    180
    Par défaut
    Bonjour Marlan,
    en effet, la synchronisation entre les différents processus et la déclaration de région parallèle sont deux choses auxquelles j'avais pensé; enfin la synchronisation, je ne vois pas vraiment ce que ça représente; mais la déclaration des variables de région parallèle, leur statut privé ou partagé, c'est surtout là dessus que j'essaye d'avancer.

    -premier point : la synchronisation entre les différents processus : je viens de passer un coup de google pour m'apercevoir que ça concerne ce qui chez OpenMP est organisé par l'utilisation des directives ATOMIC ou PARALLEL. (tout ce que je demande, moi, c'est une simple boucle DO PARALLEL)

    -deuxième point : pour la déclaration de région parallèle; j'ai fait temporairement une version simplifiée de mon code, avec juste les déclarations et les appels de sous-programmes, et aucun travail dedans, et elle plante aussi; à la fin de la longue instruction principale de OpenMP. (et cela me fait donc pressentir que je ne suis pas trop loin du compte, surtout que l'erreur est très similaire avec des symptomes très similaires également)
    Cette construction est un simple DO PARALLEL, mais avec de nombreuses clauses de statut SHARED et PRIVATE, et je ne sais pas par quel bout l\u2019attraper pour retomber sur quelque chose qui marche afin de pouvoir en revenir à mon programme complet.

    Si ça peut te donner des idées à me communiquer ensuite...
    David
    P.S. Dis Toto, pourquoi l'univers existe-t'il ?
    Je vais y réfléchir avec Morphée et lui dès avant 22h55, donc ici, il faut se causer avant.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Citation Envoyé par dva2tlse Voir le message
    en effet, la synchronisation entre les différents processus et la déclaration de région parallèle sont deux choses auxquelles j'avais pensé; enfin la synchronisation, je ne vois pas vraiment ce que ça représente; mais la déclaration des variables de région parallèle, leur statut privé ou partagé, c'est surtout là dessus que j'essaye d'avancer.
    La synchronisation est très importante, il ne faut pas qu'un thread aille trop loin et utilise des données qui auraient dues être calculées par un autre (mais qui ne l'a pas encore fait).

    Citation Envoyé par dva2tlse Voir le message
    -deuxième point : pour la déclaration de région parallèle; j'ai fait temporairement une version simplifiée de mon code, avec juste les déclarations et les appels de sous-programmes, et aucun travail dedans, et elle plante aussi; à la fin de la longue instruction principale de OpenMP. (et cela me fait donc pressentir que je ne suis pas trop loin du compte, surtout que l'erreur est très similaire avec des symptomes très similaires également)
    Cette construction est un simple DO PARALLEL, mais avec de nombreuses clauses de statut SHARED et PRIVATE, et je ne sais pas par quel bout l\u2019attraper pour retomber sur quelque chose qui marche afin de pouvoir en revenir à mon programme complet.
    Il faut aussi faire attention au statut par défaut des variables, par ex. une variable en "save" est implicitement "shared".

    Pour répondre à une question que tu posais plus haut:
    J'ai lu quelque part à propos du debugger gdb, qu'on pouvait l'utiliser sur un programme déjà en cours d'exécution; savez vous si ça pourrait m'aider et comment faire ?
    Le principe est simple: Il faut d’abord lancer le programme, et récupérer son PID (via par ex. sous Linux: ps -Aef | grep monprogramme) et depuis une autre fenêtre lancer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    gdb monprogramme PID
    Mais en fait tu pourrais aussi bien lancer ton programme avec gdb dès le début et voir où arrive le "deadlock", non?

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 152
    Points : 191
    Points
    191
    Par défaut
    Bonjour,

    Le mieux serait que tu nous donnes un exemple de ton code, ou tout du moins une partie/simplification pour que l'on puisse t'aider à le paralléliser : il n'y a pas grand chose de plus à dire : toute la difficulté de l'OpenMP de base (à comprendre sans optimisations) réside dans le statut shared ou private des variables, ainsi que dans le bon placement des synchronisations. Vis à vis des synchro par ailleurs, la 'bonne' directive à employer (outre les synchro implicites comme celles d'OMP SINGLE) est !$OMP BARRIER.

    Après vis à vis des débogueurs, je ne suis pas certain que le débogueur gdb admette l'OpenMP... Hormis dans le cas d'une exécution à un seul thread.

    En te souhaitant bon courage,

    Marlan

Discussions similaires

  1. Requete SQL avec plusieurs code
    Par r0nsync dans le forum Développement
    Réponses: 6
    Dernier message: 11/08/2010, 13h46
  2. [HTML 4.0] Code très mal écrit avec plusieurs HTML, HEAD
    Par beegees dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 17/06/2010, 15h20
  3. Réponses: 3
    Dernier message: 25/08/2009, 12h54
  4. Réponses: 6
    Dernier message: 13/10/2008, 11h44
  5. Réponses: 2
    Dernier message: 02/06/2006, 23h16

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