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 :

Faire Vectoriser une boucle avec icpc


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Faire Vectoriser une boucle avec icpc
    Bonjour,
    Voulant mimiquer le comportement de Fortran, je suis en train de faire mumuse en C++ pour faire une classe Array (d'abord en 1d).
    Je pensais "naivement" que le compilateur intel pourrait facilement m'aider à vectoriser une simple boucle où j'utilise un opérateur () pour accéder à un champ:

    bout du code de la class Array_1d:
    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
    template<class T,int Offset=DEF_OFFSET>
    class Array_1d
    {
        private:
            uint64_t n1;
            int64_t o1;
     
            T* RESTRICT ptr;
     
            // Forbid the "pass by value" in function calls
            Array_1d(const Array_1d<T,Offset>& rhs);
        public:
            // Constructors
            Array_1d(const uint64_t d1=0);
            Array_1d(const Range& r1);
     
            // Destructor
            ~Array_1d();
     
            // Array_1d<T> operators
            const Array_1d<T,Offset>& operator=(const Array_1d<T,Offset>& rhs);
            const Array_1d<T,Offset>& operator=(const T value);
     
            inline const T& operator()(const int64_t& i) const
            {
    #ifdef CHECKBOUND
                if (i<o1 || i>int64_t(o1+n1-1))
                    throw Error(1,"Out of bound");
    #endif
                return ptr[i-o1];
            }
            // OPERATEUR QUI DOIT ETRE VECTORISER EN BOUCLE SELON MOI !!!
            inline T& operator()(const int64_t& i)
            {
    #ifdef CHECKBOUND
                if (i<o1 || i>int64_t(o1+n1-1))
                    throw Error(1,"Out of bound");
    #endif
                return ptr[i-o1];
            }
     
            // Methods
            inline const T* RESTRICT get_pointer() const {return ptr;}
            inline T* RESTRICT get_pointer() {return ptr;}
     
            inline uint64_t size1() const{return n1;}
     
            inline Range range1() const{return Range(o1,o1+n1-1);}
     
            void resize(const uint64_t n_d1);
            void resize(const Range& r1);
            void free();
    };
    RESTRICT est définit en tant que restrict avec le compilo intel, et je compile avec -O3 -xSSSE3 -restrict.

    En ce qui concerne une simple boucle d'appel à l'opérateur, je fais:
    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
     
        int64_t i;
        int64_t min,max;
        Array_1d<float> array;
     
        array.resize(Range(-200,400));
        min=array.range1().min();
        max=array.range1().max();
     
    // Ne vectorise pas ???    
        for(i=min;i<=max;++i)
            array(i)=1.5;
     
     
        float* ptr=array.get_pointer();
     
    // Vectorise !!!
        for(i=min;i<=max;++i)
            ptr[i]=1.5;
    Est ce que vous avez des idées? ou est ce qu'on arrive dans les limites du/des compilos C++ qui s'arretent juste à l'inline sans passer à l'étape d'optimisation d'après (la vectorisation)?

    Faisant pas mal de calcul scientifique je trouve dommage de ne pas pouvoir vectoriser ce genre de chose... pour les performances c'est très important.

    à vos commentaires !!!

  2. #2
    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
    Salut,

    Peux-tu poster un code complet compilable ? Il manque des éléments pour l'instant.
    Si tu veux faire mumuse, je te conseille de regarder Eigen qui est la référence actuelle en terme de calcul matriciel en C++ (et même limite en terme de calcul matriciel tout court car les perfs sont équivalentes à la MKL et GOTO BLAS, même en multithreadé).

  3. #3
    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 ne connaissais pas Eigen... mais je me méfie des annonces de perf battant du BLAS etc. On peut toujours en interne gérer des calculs et les rendre aussi performant que le C ou le Fortran.
    Mais c'est moins le cas dans ce que je montre dans mon exemple. Là c'est offrir un accès à une matrice comme si on faisait du Fortran ou accéder à un tableau C directement. J'ai regardé le code source de Blitz++ ou de tvmet et ils font quasiment la même chose que ce que j'ai présenté... mais ça ne vectorise pas en externe.

    Je fournirai un code source qui compile dans la journée. Mais je reste sceptique sur l'idée d'arriver à faire vectoriser ce machin

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Blitz++ (qui n'est plus maintenu) utilise des expressions templates principalement ... Me rappelle plus si y'a de la vectorisation.

    Eigen par contre fait les deux.

  5. #5
    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
    Citation Envoyé par reptils Voir le message
    Je ne connaissais pas Eigen... mais je me méfie des annonces de perf battant du BLAS etc. On peut toujours en interne gérer des calculs et les rendre aussi performant que le C ou le Fortran.
    http://eigen.tuxfamily.org/index.php?title=Benchmark
    J'ai vu sur la ML de dev d'Eigen des benchs plus à jour.
    Citation Envoyé par reptils Voir le message
    Mais c'est moins le cas dans ce que je montre dans mon exemple. Là c'est offrir un accès à une matrice comme si on faisait du Fortran ou accéder à un tableau C directement. J'ai regardé le code source de Blitz++ ou de tvmet et ils font quasiment la même chose que ce que j'ai présenté... mais ça ne vectorise pas en externe.
    C'est faisable sans aucun problème avec vectorisation à la clé (sachant que dans le cas d'une addition, la vectorisation n'a aucun impact )
    Citation Envoyé par reptils Voir le message
    Je fournirai un code source qui compile dans la journée. Mais je reste sceptique sur l'idée d'arriver à faire vectoriser ce machin
    On va y arriver. Il suffit d'analyser ce qu'ICPC sort avec -vec-report=2, et on aura déjà une bonne idée de pourquoi il ne vectorise pour l'instant pas. Mais il faut un code simple qui compile

    (pff, tu es en vacances, tu devrais te reposer plutôt que de faire du C++, à moins de vouloir convertir HC ? )

  6. #6
    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
    Citation Envoyé par Matthieu Brucher Voir le message
    http://eigen.tuxfamily.org/index.php?title=Benchmark
    J'ai vu sur la ML de dev d'Eigen des benchs plus à jour.
    Oui j'ai vu mais comme je te le dis, ce sont des paternes qui sont gérées en interne

    C'est faisable sans aucun problème avec vectorisation à la clé (sachant que dans le cas d'une addition, la vectorisation n'a aucun impact )
    ???

    On va y arriver. Il suffit d'analyser ce qu'ICPC sort avec -vec-report=2, et on aura déjà une bonne idée de pourquoi il ne vectorise pour l'instant pas. Mais il faut un code simple qui compile
    La log peut être analysée avec le tar que je donne ci dessous... il me sort depuis hier soir la même chose (dependency FLOW ANTI... blablabla), pas moyen de faire autrement. Pour le voir il faut monter le niveau du vec-report à 3.

    (pff, tu es en vacances, tu devrais te reposer plutôt que de faire du C++, à moins de vouloir convertir HC ? )
    Non c'est juste pour faire mumuse, je voulais faire des tests par la suite...


    Tu as l'archive de mon test ici:
    http://reptils.free.fr/Developpez.tgz

    La compile me donne:
    Processing main.cpp
    icpc -c -O3 -xssse3 -g -vec-report2 main.cpp -DDEF_OFFSET=0 -DRESTRICT=restrict -restrict
    main.cpp(18): (col. 5) remark: loop was not vectorized: existence of vector dependence.
    main.cpp(24): (col. 5) remark: LOOP WAS VECTORIZED.
    main.cpp(28): (col. 10) remark: LOOP WAS VECTORIZED.
    icpc -O3 -xssse3 -g -vec-report2 -o test.bin main.o
    la ligne 18 est celle qui à mon avis devrait être vectorisée si l'inline est bien fait???

    EDIT: j'oubliais, j'ai regarder le code source de Eigen, je n'ai pas l'impression que ça fasse ce que je décrit.

  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
    Citation Envoyé par reptils Voir le message
    Oui j'ai vu mais comme je te le dis, ce sont des paternes qui sont gérées en interne
    Pas compris ce que tu voulais dire...

    Citation Envoyé par reptils Voir le message
    ???
    Pour une addition, ton facteur limitant, c'est la bande passante mémoire. Pour une multiplication, c'est différent.


    Citation Envoyé par reptils Voir le message
    La log peut être analysée avec le tar que je donne ci dessous... il me sort depuis hier soir la même chose (dependency FLOW ANTI... blablabla), pas moyen de faire autrement. Pour le voir il faut monter le niveau du vec-report à 3.
    2 ne suffit pas ?
    En tout cas, ce sont ces éléments qui indiquent ce qu'il faut faire.

    Citation Envoyé par reptils Voir le message
    la ligne 18 est celle qui à mon avis devrait être vectorisée si l'inline est bien fait???
    Pas forcément. Il y a des histoires d'assumed dependencies et proved dependencies. Si c'est de l'assumed, un #pragma ivdep résoud le pb, normalement.
    Citation Envoyé par reptils Voir le message
    EDIT: j'oubliais, j'ai regarder le code source de Eigen, je n'ai pas l'impression que ça fasse ce que je décrit.
    En meêm temps, je n'ai pas tout à fait saisi ce que tu voulais faire
    Quand tu dis comme en Fortran, c'est en pouvant travailler sur [-n,n] par exemple au lieu de [0,2n] ?

Discussions similaires

  1. [AC-2010] Faire une boucle avec recordset
    Par Grég's dans le forum VBA Access
    Réponses: 7
    Dernier message: 12/05/2015, 09h08
  2. [AC-2003] Faire une boucle avec VBA
    Par Sympa66 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 06/06/2010, 13h08
  3. Comment faire une boucle avec cette procédure
    Par soffy dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/06/2007, 22h28
  4. Faire une boucle avec des variables vides ?
    Par byloute dans le forum Linux
    Réponses: 5
    Dernier message: 23/02/2006, 09h33
  5. [DEBUTANT] sortir d'une boucle avec un touche particulière
    Par thibouille dans le forum Débuter
    Réponses: 4
    Dernier message: 25/10/2005, 06h44

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