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

Multithreading Discussion :

mappedReduced avec des fonctions objets [QtConcurrent]


Sujet :

Multithreading

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Par défaut mappedReduced avec des fonctions objets
    Bonjour,

    J'aimerais utiliser le frameworks QtConcurrent, et plus précisément la fonction mappedReduced, avec des "fonctions objets". J'ai trouvé la documentation à ce sujet, il est marqué que l'on peut les utiliser, mais je n'ai pas trouver d'exemple, et tous mes tests ne fonctionnent pas. Voici le code (exemple) que j'utilise :

    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
     
    #include <QApplication>
    #include <QtConcurrentMap>
    #include <QList>
     
    //struct Puissance;
    struct Puissance {
        Puissance(const int& p) : m_p(p) {}
        typedef double result_type;
        double operator() (const double & n) { int i = m_p; double r = 1.; while(i-->0) r*=n; return r; }
        int m_p;
    };
     
    //struct Somme;
    struct Somme
    {
        Somme() {}
        typedef void result_type;
        void operator() (double & result, const double & n) { result += n; }
    };
     
    void somme(double & result, const double & n) { result += n; }
     
    int main(int argc, char** argv)
    {
      QApplication app(argc, argv);
     
      QList<double> l;
      l << 1 << 2 << 3 << 4;
      qDebug() << l;
     
      Puissance p(8);
      Somme s;
      //  QFuture<double> res = QtConcurrent::mappedReduced(l, p, s);  // ne fonctionne pas
      QFuture<double> res = QtConcurrent::mappedReduced(l, p, somme);
      qDebug() << res.result();
     
      return app.exec();
    }
    Le but du programme est de faire la somme des éléments de la liste en les élevant au préalable à une certaine puissance. Le code posté fonctionne en utilisant la fonction somme, et ne fonctionne pas si on la remplace par l'object Somme, comme indiqué dans la ligne commentée. Je ne comprends pas pourquoi cela ne fonctionne pas, d'autant que l'object fonction Puissance est lui accepté.

    L'erreur de compilation est :
    main.cpp:33: error: no matching function for call to ‘mappedReduced(QList<double>&, Puissance&, Somme&)’
    Bien sur dans le code final, j'ai besoin d'un objet pour y stocker un état, une fonction comme "somme" ne suffit pas.

    Est ce que quelqu'un à une solution à ce problème ?

    Merci d'avance

  2. #2
    Rédacteur

    Avatar de johnlamericain
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    3 742
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 3 742
    Par défaut
    Humm pas évident et je ne connais pas beaucoup ce module.

    N'y aurait-il pas une différence entre une MapFunction et une ReduceFunction qui fait que ça ne marche pas ?

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    le compilateur n'arrive pas a déterminer le paramètre template ResultType.
    Il te suffit de le définir toi même.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     QFuture<double> res = QtConcurrent::mappedReduced<double>(l, p, s,QtConcurrent::SequentialReduce);
    Par contre, j'ai regardé un peu ce qui se passe, et les foncteur sont recopier pas mal de fois.... A en tenir compte a mon avis (je pense que suivant le foncteur, le compilo vire ces copie si elles sont inutilent)
    voici le code qui t'affiche toutes les recopies de Somme et Puissance.



    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
    #include <QApplication>
    #include <QtConcurrentMap>
    #include <QList>
     
    //struct Puissance;
    struct Puissance {
        Puissance(const int& p) : m_p(p) {}
     
        Puissance() {qDebug()<<"Puissance";}
        Puissance(const Puissance & p) {m_p =p.m_p; qDebug()<<" Puissance(const &)";}
        Puissance &operator=(const Puissance & p){m_p =p.m_p;qDebug()<<"Puissance operator="; return *this;}
     
        typedef double result_type;
        double operator() (const double & n) { int i = m_p; double r = 1.; while(i-->0) r*=n; return r; }
        int m_p;
    };
     
    //struct Somme;
    struct Somme
    {
        Somme() {qDebug()<<"Somme";}
        Somme(const Somme & ) {qDebug()<<" Somme(const &)";}
        Somme &operator=(const Somme & ){qDebug()<<"Somme operator="; return *this;}
     
        void operator() (double & res, double  n) {res += n ; }
    };
     
    void somme(double & result, double  n) { result += n; }
     
    int main(int argc, char** argv)
    {
      QApplication app(argc, argv);
     
      QList<double> l;
      l << 1 << 2 << 3 << 4;
      qDebug() << l;
     
      Puissance p(8);
      Somme s;
      QFuture<double> res = QtConcurrent::mappedReduced<double>(l, p, s,QtConcurrent::SequentialReduce);  
      //QFuture<double> res = QtConcurrent::mappedReduced(l, p, somme);
      res.waitForFinished();
      qDebug() << res.result();
     
      return 0;
    }

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Par défaut
    c'est super, merci beaucoup !

    C'est vrai qu'il fait beaucoup de copie, je vais essayer de voir si leur nombre est proportionnel à la taille de la séquence en entrée (j'ai bien peur que oui).

    J'ai juste 2 questions : comment retirer les warning quand on compile en release (avec -O2) ? à moins qu'il n'y ait que moi qui les ai

    Et sinon, si par exemple à la place de vouloir faire une somme, je voulais faire un produit, est ce qu'il y a un moyen pour passer un objet déjà initialisé comme accumulateur ? Pour le produit il faudrait 1, et non 0 comme pour la somme.

    Merci beaucoup en tout cas, et chapeau pour la réactivité, comme d'habitude

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Le Mérovingien Voir le message
    J'ai juste 2 questions : comment retirer les warning quand on compile en release (avec -O2) ? à moins qu'il n'y ait que moi qui les ai
    En les traitants.
    Quel warning?

    Et sinon, si par exemple à la place de vouloir faire une somme, je voulais faire un produit, est ce qu'il y a un moyen pour passer un objet déjà initialisé comme accumulateur ? Pour le produit il faudrait 1, et non 0 comme pour la somme.
    je sais pas. Je pense que c'est au foncteur reduce de gérer cela.
    A voir

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Par défaut
    Déjà une bonne nouvelle, le nombre de copies de Puissance et Somme est constant et égal à 5 on dirait, il n'augmente pas avec le nombre d'éléments dans la séquence.

    Pour les warning à la compilation, voila le log :
    g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
    In file included from /usr/include/qt4/QtCore/qfuture.h:49,
    from /usr/include/qt4/QtCore/qtconcurrentthreadengine.h:50,
    from /usr/include/qt4/QtCore/qtconcurrentiteratekernel.h:51,
    from /usr/include/qt4/QtCore/qtconcurrentmapkernel.h:49,
    from /usr/include/qt4/QtCore/qtconcurrentmap.h:49,
    from /usr/include/qt4/QtCore/QtConcurrentMap:1,
    from main.cpp:2:
    /usr/include/qt4/QtCore/qmap.h: In destructor ‘QFutureInterface<T>::~QFutureInterface() [with T = double]’:
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    /usr/include/qt4/QtCore/qmap.h: In destructor ‘QFutureInterface<T>::~QFutureInterface() [with T = double]’:
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    /usr/include/qt4/QtCore/qmap.h: In function ‘int main(int, char**)’:
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    /usr/include/qt4/QtCore/qmap.h:588: warning: dereferencing pointer ‘y’ does break strict-aliasing rules
    /usr/include/qt4/QtCore/qmap.h:586: note: initialized from here
    g++ -Wl,-O1 -o qtconcurrent main.o -L/usr/lib -lQtGui -lQtCore -lpthread
    Je ne sais pas ce que ça veut dire "dereferencing pointer ‘y’ does break strict-aliasing rules", mais je me doute que c'est une erreur dans le compilateur. Je suis sous linux et j'utilise GCC 4.4.1 fourni par ubuntu karmic, avec Qt 4.5.2. Je précise que ces warning apparaissent seulement quand je mets release dans la variable CONFIG du fichier .pro, et je pense que plus précisément cela est du à l'option -O2.

    Enfin, pour la première valeur de l'accumulateur, je ne pense pas que l'on puisse faire quelque chose avec l'objet foncteur, puisque l'accumulateur est passé par référence comme premier argument de l'operateur (). Par contre, on pourrait créer son propre type d'accumulateur avec un constructeur par défaut qui initialise sa valeur comme on veut. Est ce qu'il existe en C++ une classe Integer comme en Java, et dont on pourrait faire une sous classe avec une valeur par défaut à 1 à la place de 0 ? Je ne pense pas mais on ne sais jamais, et puis le problème c'est que ce n'est pas très flexible. Si quelqu'un à une meilleure solution, je suis preneur.

    Merci pour les réponses en tout cas.

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

Discussions similaires

  1. problème avec des fonctions
    Par teen6517 dans le forum Langage
    Réponses: 1
    Dernier message: 12/03/2007, 13h34
  2. Réponses: 3
    Dernier message: 15/02/2007, 09h54
  3. erreur LNK2019 avec des fonctions communes.
    Par FamiDoo dans le forum Visual C++
    Réponses: 9
    Dernier message: 31/07/2006, 10h32
  4. Compilation avec des fonctions virtuel pure
    Par vanitom dans le forum C++
    Réponses: 4
    Dernier message: 16/12/2005, 14h37
  5. petit souci avec des variables avec des fonctions psql
    Par dust62 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/04/2005, 13h45

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