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

C++ Discussion :

Comment obtenir le maximum de performance (calcul) ?


Sujet :

C++

  1. #1
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut Comment obtenir le maximum de performance (calcul) ?
    Il y a une dizaine d'années, plusieurs articles sont parus pour montrer que C++ pouvait avoir des performances égales ou équivalentes au Fortran. En particulier, on pouvait s'appuyer sur la bibliothèque Blitz++ (http://www.oonumerics.org/blitz/).
    Depuis, j'ai refait des tests sur plusieurs plateformes. Les performances en Fortran sont bien plus impressionnantes en Fortran 90 qu'en Fortran 77 (un facteur 2 est courant). Même certaines versions "tunées" sont plus lentes que les versions classiques. Cela s'inverse par exemple sur le bench acoustique 2D si on prend un modèle de taille 6500*6500 (donc 100 fois plus important).

    Pour en revenir au C++, les performances sont actuellement inférieures à celles de Fortran sur ces benchs avec les compilateurs actuels (ICC 10 ou 11, PGI 8, sur plusieurs plateformes comme les Xeon avec architecture Core, Opteron, Itanium). Même en indiquant au compilateur que les arguments ne peuvent pas être aliasés (-fno-fnalias pour GCC et ICC par exemple, tout en sachantq ue ces options sont dangereuses, ou en utilisant le mot-clé C99 restrict sur des benchs C), il n'est pas toujours possible d'obtenir les mêmes performances qu'en Fortran (sur d'autres benchs).

    Ce post est donc proposé ici pour voir quelles sont les solutions pour approcher les performances maximales... Pour l'instant, je n'en ai pas

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Avant de parler solution, parlons problème

    Tu as un bench particulier et simple où la solution C++ est plus lente que la solution Fortran ? Tu as eu l'occasion de l'analyser pour voir qu'est-ce qui faisait la différence ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Le bench Blitzz++, la version Acoustic 2D et 3D (il peut tout de même y avoir un facteur 2 ou 3 entre les versions, c'est dire...). Je vais essayer de faire plus simple demain avec juste 2 ou 3 boucles for imbriquées.

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Un exemple simple, mais assez représentatif :
    La version C++ (c'est quasiment du C) :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <iostream>
    #include <cstdlib>
     
    #define XYZ(x, y, z, N) ((x) + (y) * (N) + (z) * (N) * (N))
     
    void compute(float* P, float* Q, int N);
     
    int main(int argc, char** argv)
    {
      const int N = 100;
      const int iter = 100;
     
      float* P = new float[N*N*N];
      float* Q = new float[N*N*N];
     
      for(int i = 0; i < N*N*N; ++i)
      {
        P[i] = 1500;
        Q[i] = 1500;
      }
     
      for(int i = 0; i < iter; ++i)
      {
        compute(P, Q, N);
        compute(Q, P, N);
      }
     
      std::cout << P[XYZ(N/2, N/2, N/2, N)] << std::endl;
     
      delete[] P;
      delete[] Q;
     
      return EXIT_SUCCESS;
    }
     
    void compute(float* P, float* Q, int N)
    {
      for(int k = 4; k < N-4; ++k)
      {
        for(int j = 4; j < N-4; ++j)
        {
          for(int i = 4; i < N-4; ++i)
          {
            Q[XYZ(i, j, k, N)] = P[XYZ(i, j, k, N)]
              + (P[XYZ(i+1, j, k, N)] - P[XYZ(i-1, j, k, N)])
              + (P[XYZ(i+2, j, k, N)] - P[XYZ(i-2, j, k, N)])
              + (P[XYZ(i+3, j, k, N)] - P[XYZ(i-3, j, k, N)])
              + (P[XYZ(i+4, j, k, N)] - P[XYZ(i-4, j, k, N)])
              + (P[XYZ(i, j+1, k, N)] - P[XYZ(i, j-1, k, N)])
              + (P[XYZ(i, j+2, k, N)] - P[XYZ(i, j-2, k, N)])
              + (P[XYZ(i, j+3, k, N)] - P[XYZ(i, j-3, k, N)])
              + (P[XYZ(i, j+4, k, N)] - P[XYZ(i, j-4, k, N)])
              + (P[XYZ(i, j, k+1, N)] - P[XYZ(i, j, k-1, N)])
              + (P[XYZ(i, j, k+2, N)] - P[XYZ(i, j, k-2, N)])
              + (P[XYZ(i, j, k+3, N)] - P[XYZ(i, j, k-3, N)])
              + (P[XYZ(i, j, k+4, N)] - P[XYZ(i, j, k-4, N)]);
          }
        }
      }
    }
    La version Fortran :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    PROGRAM test2Df
     
      IMPLICIT NONE
     
      REAL, ALLOCATABLE :: P(:,:,:)
      REAL, ALLOCATABLE :: Q(:,:,:)
     
      INTEGER N, iter
     
      INTEGER i
     
      N = 100
      iter = 100
     
      ALLOCATE(P(N,N,N))
      ALLOCATE(Q(N,N,N))
     
      P(:,:,:) = 1500
      Q(:,:,:) = 1500
     
      do i = 1, iter
        CALL COMPUTE(P, Q, N)
        CALL COMPUTE(Q, P, N)
      enddo
     
      PRINT *, P(N/2+1,N/2+1,N/2+1)
     
      DEALLOCATE(P)
      DEALLOCATE(Q)
     
    END PROGRAM
     
    SUBROUTINE COMPUTE(P, Q, N)
     
      IMPLICIT NONE
     
      REAL :: P(N,N,N)
      REAL :: Q(N,N,N)
      INTEGER :: N
     
      INTEGER i, j, k
     
      do k = 5, N-4
        do j = 5, N-4
          do i = 5, N-4
            Q(i, j, k) = P(i, j, k) &
              + (P(i-1, j, k) - P(i+1, j, k)) &
              + (P(i-2, j, k) - P(i+2, j, k)) &
              + (P(i-3, j, k) - P(i+3, j, k)) &
              + (P(i-4, j, k) - P(i+4, j, k)) &
              + (P(i, j-1, k) - P(i, j+1, k)) &
              + (P(i, j-2, k) - P(i, j+2, k)) &
              + (P(i, j-3, k) - P(i, j+3, k)) &
              + (P(i, j-4, k) - P(i, j+4, k)) &
              + (P(i, j, k-1) - P(i, j, k+1)) &
              + (P(i, j, k-2) - P(i, j, k+2)) &
              + (P(i, j, k-3) - P(i, j, k+3)) &
              + (P(i, j, k-4) - P(i, j, k+4))
          enddo
        enddo
      enddo
     
    END SUBROUTINE
    Compilé avec ICC 10.1.018 (-O2 par défaut), j'obtiens 3.3s pour le C++ et 1.7s pour le Fortran...

    Comme je l'ai dit, il y a des extensions qui me permettent d'optimiser, mais ce ne sont pas des extensions officielles, elles viennent sur le C99, mais je ne sais pas si elles intègreront C0x. Donc si je mets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void compute(float* __restrict__ P, float* __restrict__ Q, int N)
    Là, j'ai des perfs identiques. Mais ce n'est pas standard. De plus, c'est sur une signature, la fonction que j'utilise réellement est une structure qui englobe plusieurs P et Q (car le stencil est plus complexe).

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    float == real ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Oui, pardon, les real Fortran sont des flottants 32bits.

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Je confirme, je viens de tester ce code :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    #include <iostream>
    #include <cstdlib>
     
    #define XYZ(x, y, z, N) ((x) + (y) * (N) + (z) * (N) * (N))
     
    struct Test
    {
      float* __restrict__ P;
      float* __restrict__ Q;
    };
     
    void compute(Test* test, int N);
     
    int main(int argc, char** argv)
    {
      const int N = 100;
      const int iter = 100;
     
      Test *test;
      test = new Test();
      test->P = new float[N*N*N];
      test->Q = new float[N*N*N];
     
      for(int i = 0; i < N*N*N; ++i)
      {
        test->P[i] = 1500;
        test->Q[i] = 1500;
      }
     
      for(int i = 0; i < 2*iter; ++i)
      {
        compute(test, N);
        std::swap(test->P, test->Q);
      }
     
      std::cout << test->P[XYZ(N/2, N/2, N/2, N)] << std::endl;
     
      delete[] test->P;
      delete[] test->Q;
      delete test;
     
      return EXIT_SUCCESS;
    }
     
    void compute(Test *test, int N)
    {
      for(int k = 4; k < N-4; ++k)
      {
        for(int j = 4; j < N-4; ++j)
        {
          for(int i = 4; i < N-4; ++i)
          {
            test->Q[XYZ(i, j, k, N)] = test->P[XYZ(i, j, k, N)]
              + (test->P[XYZ(i+1, j, k, N)] - test->P[XYZ(i-1, j, k, N)])
              + (test->P[XYZ(i+2, j, k, N)] - test->P[XYZ(i-2, j, k, N)])
              + (test->P[XYZ(i+3, j, k, N)] - test->P[XYZ(i-3, j, k, N)])
              + (test->P[XYZ(i+4, j, k, N)] - test->P[XYZ(i-4, j, k, N)])
              + (test->P[XYZ(i, j+1, k, N)] - test->P[XYZ(i, j-1, k, N)])
              + (test->P[XYZ(i, j+2, k, N)] - test->P[XYZ(i, j-2, k, N)])
              + (test->P[XYZ(i, j+3, k, N)] - test->P[XYZ(i, j-3, k, N)])
              + (test->P[XYZ(i, j+4, k, N)] - test->P[XYZ(i, j-4, k, N)])
              + (test->P[XYZ(i, j, k+1, N)] - test->P[XYZ(i, j, k-1, N)])
              + (test->P[XYZ(i, j, k+2, N)] - test->P[XYZ(i, j, k-2, N)])
              + (test->P[XYZ(i, j, k+3, N)] - test->P[XYZ(i, j, k-3, N)])
              + (test->P[XYZ(i, j, k+4, N)] - test->P[XYZ(i, j, k-4, N)]);
          }
        }
      }
    }
    Sa vitesse d'exécution est de 3.2 secondes, idem si on enlève le "__restrict__". Donc icc n'est pas capable d'optimiser ce type de code, il faut que les tableaux soient passés en argument directement. Or, ce n'est pas possible pour moi car selon le calcul de la boucle (le stencil), j'utilise plus ou moins de tableaux.

    Bref, il ya deux sous-questions à ma question principale, puisqu'on peut obtenir des performances comparables :
    - est-ce que le C++ va adopter un restrict-like ?
    - comment faire comprendre au compilateur qu'il peut y aller sans avoir à réécrire la boucle pour chaque stencil ?

  8. #8
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    la différence peut peut-être s'expliquer par l'usage de SSE2 avec fortran et pas sur la version compilée par ICC.
    si tu ne spécifies pas la cible à ICC, options /q et /arch, il n'y a pas d'optimisation SSE2

    http://software.intel.com/en-us/arti...optimizations/

    apparemment d'après la doc

    On IA-32 systems running Windows* and Linux*, /arch:SSE2 is on by default. The resulting code path should run on the Intel Pentium 4 and Intel Xeon processors with SSE2 support and other compatible processors with SSE2 support.
    à vérifier ...

    et essayer d'autres options comme le déroulement des boucles ... ?

    @+

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    J'utilise -xW sur les deux compilateurs, et c'est du 64 bits (j'ai oublié de préciser ), donc pas de pb.
    Le souci se trouve au niveau de l'aliasing des pointeurs utilisés.

  10. #10
    screetch
    Invité(e)
    Par défaut
    La mémoire allouée par new est garantie de ne jamais aliasé donc il devrait pouvoir s'en rendre compte (le salaaaud)
    si tu mets ta fonction avant, et que tu la declare static inline, va t'il s'en rendre compte ?

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Il faut voir que le code réel est bien plus complexe. En fait la boucle de calcul est template avec une classe Computation et le stencil appelé est un Computation::boucle(test) avec toutes les variables qui vont bien dans la même structure. Je pourrais inverser, mais pas sûr que cela apporte grand chose, sachant qu'une partie des tableaux doit être allouée à l'extérieur de l'unité de compilation (je ne me repose pas sur -ipo) pour être initialisée correctement.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    plop!
    J'ai testé vite fait chez avec gcc -O2 sous cygwin j'ai pas eu de différences avec et sans le __restrict__. Je testerai ça demain sur la bécane avec icc.

    Sinon j'ai une question bete. Est ce que dans le main si tu remplaces tes float* par des vector<float> et que tu passes l'adresse du premier élément dans le compute, as-tu le même comportement avec icc?

  13. #13
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Aucune idée, mais je ne pense pas que cela change quoique ce soit
    De plus, ce n'est pas possible de passer l'adresse du vecteur dans la boucle. J'ai une signature fixe qui est celle donnée.

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    je te parle de faire un truc du genre:
    compute(&P[0], &Q[0], N);
    avec P et Q des vector<float>
    C'était histoire de voir si en mettant une micro couche objet le compilo icc arrivait à se dépatouiller.

  15. #15
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Si tu fais ça, ça ne change rien. Les pointeurs peuvent être aliasés. Tu mets en revanche un __restrict__, et ça marche, comme je l'ai dit dans mon premier post

  16. #16
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    De mémoire, un valarray<float> a la garantie de ne pas être aliasé, et un compilateur bien fait peut utiliser cette garantie. Mais valarray est passé de mode, et je ne suis pas certain que des compilateurs l'utilisent.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  17. #17
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Les performances des valarray n'ont pas l'air d'être meilleures sur mes benchs que Blitz, donc le compilateur ne doit pas s'en sortir non plus.
    En fait, je me rend compte aussi que même en Fortran cette écriture (passer une structure en paramètre) va empêcher le compilateur de faire des optimisations : les deux pointeurs ne sont pas passés séparément, et dans la structure il peut y avoir des pointeurs aliasés (par exemple un tableau et et une vue sur ce même tableau, ça peut avoir un sens). Donc mon problème est maintenant de pouvoir trouver un moyen plus ou moins élégant d'avoir un template pour la structure de ma boucle (parce que ce n'est pas qu'une triple boucle for en réalité, il y a des appels au stencil à chaque étage à cause de la gestion des bords, la boucle allant de 0 à N-1 dans le vrai code).
    Je sens que chaque stencil va définir une macro avant d'inclure l'en-tête de la boucle

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    Moi je sens que tu vas tout simplement passer au fortran
    non j'déconne...

    Bon j'ai testé de mon coté, et j'ai les même comportement que toi avec le compilo icc. Inquiétant que pour la portabilité ça ne soit pas le cas, car avec g++ ça ne fonctionne pas! à moins que le __restrict__ ne soit pas reconnu dans le g++ car c'est de la norme C99 et que ce soit vaguement rempalcé par autre chose?

    Pour ton probleme de portabilité tu pourrais mettre tes computes en Fortran et les appeler depuis le cpp en passant les pointeurs. J'ai testé et ça fonctionne. J'ai 1.69 sec comme avec le "__restrict__". Après je ne sais pas si dans ton code ça t'arrange ou pas.

  19. #19
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Je viens de tester la méthode Fortran avec une structure au lieu du passage explicite des 2 tableaux, donc quelque chose qui ressemble à ce que je veux faire (une interface unique pour des stencils plus ou moins compliqués). J'obtiens 3.7s. Donc moins bien que le C++.
    Ca me conforte dans mes choix, mais j'aimerai tout de même taquiner la vitesse optimale

  20. #20
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    J'ai du mal à voir en quoi __restrict__ permet de gagner un facteur 2 sur ce genre de boucle. As tu regardé le code assembleur généré dans les deux cas ?

    Avec Visual2005, __restrict ne change rien, par contre compiler le code en SSE(2) fait perdre un facteur 2 !

Discussions similaires

  1. comment obtenir différents calcul dans état
    Par Domi70 dans le forum IHM
    Réponses: 10
    Dernier message: 16/02/2009, 00h06
  2. Comment obtenir la valeur d'un calcul ?
    Par EGSway dans le forum IHM
    Réponses: 4
    Dernier message: 21/06/2007, 19h14
  3. comment obtenir un polynome de regression
    Par evariste_galois dans le forum Mathématiques
    Réponses: 17
    Dernier message: 19/01/2007, 15h06
  4. Comment obtenir l'heure du serveur avec flash ?
    Par Michaël dans le forum Flash
    Réponses: 9
    Dernier message: 23/12/2003, 17h50
  5. Comment obtenir la liste des paramètres d'une SP ?
    Par Le Gritche dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 14/03/2003, 16h54

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