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

Fortran Discussion :

Problème de performance d'une subroutine FORTRAN


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 6
    Par défaut Problème de performance d'une subroutine FORTRAN
    Bien le bonjour,

    Dans notre labo nous développons un solveur de mécanique des fluides en fortran. Je me suis décidé la semaine dernière à tenter de l'optimiser. J'ai donc commencé par le profiling: gprof, oprofile et Intel Vtune sont formels; une de mes subroutines consomment 20% du temps...alors qu'elle ne le devrait pas. donc j'ai un pb.

    Sous oprofile ou sous Vtune on peut voir quelles sont les lignes de code consommant le plus de CPU. A notre grande surprise toutes les boucles DO servant à remettre à Zero les vecteurs consomment énormément de temps!!! Je fais par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    do inp=icst,icen
         su(inp)=d0
         pp(inp)=d0
    enddo
    ce qui est vraiment étrange c'est que qd je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    do inp=icst,icen
         su(inp)=d0
    enddo
    do inp=icst,icen
         pp(inp)=d0
    enddo
    ces boucles DO n'apparaissent plus comme "hotspot" sous Vtune par exemple...à la place intel_new_memset (j'utilise intel fortran compiler) fait son apparition dans les subroutines consommant bcp de CPU.

    Quelqu'un a une explication sur ce comportement. des liens ? une solution ?
    Merci d'avance!

  2. #2
    Membre éprouvé
    Homme Profil pro
    Ingénieur modélisation aérodynamique
    Inscrit en
    Juillet 2009
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur modélisation aérodynamique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2009
    Messages : 105
    Par défaut
    Bonjour,

    C'est effectivement plus judicieux de faire deux boucles séparées. C'est un problème similaire au parcours d'un tableau à 2 dimensions :
    Pour respecter l'organisation des tableaux en mémoire, la boucle suivante est préférable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do j=1,n
       do i=1,n
          A(i,j) = ...
       enddo
    enddo
    à celle-ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do i=1,n
       do j=1,n
          A(i,j) = ...
       enddo
    enddo
    Dans votre cas, le problème est similaire, les 2 tableaux sont stocké à des adresses différentes :
    adresse1 : tab1(1),tab1(2),...tab1(n)
    adresse2 : tab2(1),tab2(2),...tab2(n)

    L'écriture que vous proposez en 1 seule boucle l'oblige à changer d'adresse mémoire à chaque itération. Alors que la seconde écriture parcours la même adresse de proche en proche puis passe à la seconde adresse.

    Vous pouvez également utiliser l'écriture vectorielle, lorsque c'est possible, qui est préférable à une boucle explicite pour le temps de calcul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    su(icst:icen) = d0
    pp(icst:icen) = d0

  3. #3
    Nouveau membre du Club
    Inscrit en
    Février 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 6
    Par défaut
    Bonjour,

    merci de votre réponse.

    J'ai fait un test comparatif entre une boucle explicitement écrite et la version vectorielle. Avec notre programme il n'y a "pas" de grandes différences. Je vais y faire attention à l'avenir et tester la chose.

    Merci encore!

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Par défaut
    Quand tu as séparé la boucle en 2 pour initialiser séparément tes vecteurs, le compilateur a décider d'utiliser la fonction intel_new_memset. Le compilateur avant donc déjà converti la boucle en opération globale d'initialisation. La version vectorielle ne devrait pas avoir changé la stratégie du compilateur; la performance devrait donc être la même...

Discussions similaires

  1. Utiliser une subroutine fortran en C
    Par chaponinho dans le forum Linux
    Réponses: 1
    Dernier message: 28/04/2008, 20h08
  2. Problème de performance avec une regexp
    Par NicoV dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 21/02/2008, 18h46
  3. Problèmes de performances sur une base oracle 10g
    Par ORAMEL dans le forum Oracle
    Réponses: 3
    Dernier message: 11/09/2007, 09h11
  4. Réponses: 2
    Dernier message: 28/08/2006, 13h16
  5. Problème de performance sur une "grosse" BD
    Par frechy dans le forum Installation
    Réponses: 9
    Dernier message: 19/09/2005, 16h52

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