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 :

multi threading c++


Sujet :

C++

Vue hybride

mohsenuss91 multi threading c++ 04/03/2015, 09h40
ternel As-tu idée de ce que tu veux... 04/03/2015, 10h05
mohsenuss91 Au fait, je veux utiliser les... 04/03/2015, 10h10
ternel Tu n'y gagneras rien, parce... 04/03/2015, 10h26
imperio Si il fait du traitement sur... 04/03/2015, 10h45
mohsenuss91 ça veux dire quoi le mmap ? 04/03/2015, 11h28
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut multi threading c++
    Bonjour, J'ai fais un programme pour la lecture des graphes à partir d'un fichier:
    Code x : 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
    t # 0
    v 0 0
    v 1 3
    v 2 9
    e 2 1 68
    e 0 1 10
    e 0 2 4
    t # 1
    v 0 2
    v 1 11
    v 2 6
    v 3 10
    v 4 18
    v 5 14
    e 0 1 15
    e 2 5 19
    e 1 3 20
    t # 2
    v 0 6
    v 1 11
    e 0 1 13
    t # 3
    v 0 2
    v 1 11
    v 2 19
    v 3 2
    e 0 1 15
    e 1 2 11
    e 0 3 19
    t # 4
    v 0 1
    v 1 16
    v 2 14
    e 0 1 8
    e 1 2 5
    e 0 2 19

    et je veux l'améliorer surtout en ce qui concerne le temps d’exécution, donc j'ai pensé à utiliser le multithreading mais j'ai aucune idée d'où commencer. J'ai lu quelques exemples (la plupart utilise les méthodes et les fonctions qui ne sont pas dans mon programme).

    J'attends vos propositions.

    voila le 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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/vf2_sub_graph_iso.hpp>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <ctime>
    using namespace std;
    using namespace boost;
     
    /*********************************************/
    // vertex
    struct VertexProperties {
        int id;
        int label;
        VertexProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // edge
    struct EdgeProperties {
        unsigned id;
        unsigned label;
        EdgeProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // Graph
    struct GraphProperties {
        unsigned id;
        unsigned label;
        GraphProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // adjency list
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
            VertexProperties,
            EdgeProperties,
            GraphProperties> Graph;
     
    // descriptors
     
    typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
    typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
    // iterators
    typedef graph_traits<Graph>::vertex_iterator vertex_iter;
    typedef graph_traits<Graph>::edge_iterator edge_iter;
     
    int main()
    {
        clock_t start=std::clock();
        std::vector<Graph> dataG;
     
        std::ifstream file_reader("1000.data"); // flux d'entrée pour opérer sur les fichiers.
        //ifstream * file_reader= new ifstream("60.txt" ); //flux d'entrée pour opérer sur les fichiers.
     
        std::string line;
        while (std::getline(file_reader, line)) { // getline reads characters from an input stream and places them into a string
     
            char lineType;
     
            std::stringstream ss(line);  // use a string buffer that contains a sequence of characters.
            if (ss >> lineType) switch (lineType) {
                case 't':
                    {
                        char diez;
                        unsigned gid;
                        if (ss >> diez >> gid) {
                            dataG.emplace_back(GraphProperties (gid, gid));
                            //dataG.push_back(GraphProperties (gid, gid));
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
                case 'v':
                    {
                        assert(!dataG.empty());
     
                        int vId, vLabel;
                        if (ss >> vId >> vLabel) {
                            boost::add_vertex(VertexProperties(vId, vLabel), dataG.back());
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
                case 'e':
                    {
                        assert(!dataG.empty());
     
                        int fromId, toId, vLabel;
                        if (ss >> fromId >> toId >> vLabel) {
                            // Note that the EdgeProperty.id doesn't make sense with your input data
                            // as it only contains [vertexFrom vertexTo edgeData]
                            boost::add_edge(fromId, toId, EdgeProperties(vLabel, vLabel), dataG.back());
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
            } else
            {
                // ignoring empty line
            }
        }
    }

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    As-tu idée de ce que tu veux distribuer?
    Qu'y gagneras-tu?

    Sans réponses à ces deux questions, n'essaie même pas de multi-threader.
    En général, ajouter un thread permet de séparer par exemple l'interface graphique du traitement.

    Ajouter des threads ne peut servir que si on sait qu'on y gagnera.
    Dans le cas contraire, ca risque de ralentir l'exécution du programme, et ca va forcément beaucoup ralentir son développement et sa clarté.

  3. #3
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    Au fait, je veux utiliser les threads pour la lecture de chaque graphe pour gagner plus de temps.
    j'ai modifié le programme précédent:
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/vf2_sub_graph_iso.hpp>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <ctime>
    using namespace std;
    using namespace boost;
     
    /*********************************************/
    // vertex
    struct VertexProperties {
        int id;
        int label;
        VertexProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // edge
    struct EdgeProperties {
        unsigned id;
        unsigned label;
        EdgeProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // Graph
    struct GraphProperties {
        unsigned id;
        unsigned label;
        GraphProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
    };
     
    // adjency list
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, 
            VertexProperties, 
            EdgeProperties,
            GraphProperties> Graph;
     
    // descriptors
     
    typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
    typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
    // iterators
    typedef graph_traits<Graph>::vertex_iterator vertex_iter;
    typedef graph_traits<Graph>::edge_iterator edge_iter;
    //==================================================================================
    std::vector<Graph> readandcreategraphs(string fich)
    {
    	std::vector<Graph> vect;
     
        std::ifstream file_reader(fich); // flux d'entrée pour opérer sur les fichiers.
        //ifstream * file_reader= new ifstream("60.txt" ); //flux d'entrée pour opérer sur les fichiers.
     
        std::string line;
        while (std::getline(file_reader, line)) { // getline reads characters from an input stream and places them into a string
     
            char lineType;
     
            std::stringstream ss(line);  // use a string buffer that contains a sequence of characters.
            if (ss >> lineType) switch (lineType) {
                case 't':
                    {
                        char diez;
                        unsigned gid;
                        if (ss >> diez >> gid) {
                            vect.emplace_back(GraphProperties (gid, gid));//1000.data>>3,381s
                            //vect.push_back(GraphProperties (gid, gid));//1000.data>>3,7776s
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
                case 'v':
                    {
                        assert(!vect.empty());
     
                        int vId, vLabel;
                        if (ss >> vId >> vLabel) {
                            boost::add_vertex(VertexProperties(vId, vLabel), vect.back());
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
                case 'e':
                    {
                        assert(!vect.empty());
     
                        int fromId, toId, vLabel;
                        if (ss >> fromId >> toId >> vLabel) {
                            // Note that the EdgeProperty.id doesn't make sense with your input data
                            // as it only contains [vertexFrom vertexTo edgeData]
                            boost::add_edge(fromId, toId, EdgeProperties(vLabel, vLabel), vect.back());
                        }
                        else throw std::runtime_error("Error parsing '" + line + "'");
                    }
                    break;
            } else
            {
                // ignoring empty line
            }
        }
     return vect;
    }
     
    //==================================================================================
     
    int main() 
    {
    	clock_t start=std::clock();
    	std::vector<Graph> dataG= readandcreategraphs("1000.data");
    //std::cout << "Lecture et creation de:" << dataG.size() << " graphs " << std::endl;
       	Graph testg;
       	typedef std::pair<edge_iter, edge_iter> edge_pair;
     
        cout<<"TIME: "<<( std::clock() - start ) / (double) CLOCKS_PER_SEC<<"s"<<endl; // fin du programme.
     
    }

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu n'y gagneras rien, parce que le problème c'est que tes graphes sont dans un/des fichiers, et qu'il faut lire ces fichiers.
    Ce n'est pas tellement le graphe qui pose problème, mais le disque dur.

    éventuellement, recherche du coté de mmap.

  5. #5
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 871
    Par défaut
    Si il fait du traitement sur les fichiers, il peut threader l'appel à mmap pendant que le thread principal fait son traitement, ça sera toujours ça de gagner.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Si tu débutes avec C++, tu n'en es pas à threader.
    Un thread n'est pas un baguette magique, c'est un moyen de répartir le travail.

    Encore faut-il savoir quel travail peut-être fait à coté d'un autre, et en quoi ca n'utilise pas le même ressources (ici un fichier)

  7. #7
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Par défaut
    Citation Envoyé par leternel Voir le message
    Tu n'y gagneras rien, parce que le problème c'est que tes graphes sont dans un/des fichiers, et qu'il faut lire ces fichiers.
    Ce n'est pas tellement le graphe qui pose problème, mais le disque dur.

    éventuellement, recherche du coté de mmap.
    ça veux dire quoi le mmap ?

  8. #8
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu ne peux pas continuer à lire le fichier pendant que tu le lis.
    Si encore tu avais plusieurs fichiers, tu pourrais charger chacun dans un thread (en réutilisant les threads qui ont déjà fini... cf thread pool)

    Un fichier, c'est rare et cher. c'est même pour ca qu'un fstream n'est pas copiable.
    Ca n'est pas vraiment partageable entre threads.

    En regardant ton code, tout me parait légitime.
    Par contre, je pense que tu ne compiles pas avec les optimisations de performances.
    Pour gcc, c'est -O2, voire -O3, si vraiment c'est nécessaire.



    mmap est une fonction qui permet de "mapper en mémoire" un fichier, et donc de charger un fichier plus vite.
    Par contre, derrière, tu le manipules comme un énorme tableau de char.

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. Réponses: 2
    Dernier message: 15/05/2004, 18h33
  3. Réponses: 16
    Dernier message: 30/01/2004, 11h05
  4. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

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