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 :

Augmenter le nombre d'éléments dans un vecteur


Sujet :

C++

  1. #1
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut Augmenter le nombre d'éléments dans un vecteur
    Bonjour
    je voudrais créer un mouvement brownien, qui possède un grand nombre de points, supérieur à 10^7.
    J'ai fait le code suivant:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vector<double> brownien; 
    for(long i=1;i<pow(10,7.0);i++){
    	a=brownien[i-1]+pow((double)i/res,0.5)*norm_dist.operator()<boost::lagged_fibonacci19937>(engine);
        brownien.push_back(a);
    	}

    mais dès qu'on passe à 10^8, le programme sature.

    Ensuite, je me suis dit qu'on va créer un autre vecteur, à la suite du premier, comme ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    vector<double> brownien2;
    brownien2.push_back(brownien[pow(10,7.0)-1]+pow((double)(pow(10,7.0))/res,0.5)*norm_dist.operator()<boost::lagged_fibonacci19937>(engine));
     
        for(long i=pow(10,7.0)+1;i<pow(10,8.0);i++){
    	a=norm_dist.operator()<boost::lagged_fibonacci19937>(engine);
        brownien2.push_back(a);
        	}
    mais bien sur cela plante, le nombre maximal de pointeurs à été atteint. Alors je ne vois pas du tout comment résoudre le pb. J'aimerais bien passer à 10^9 points, pour faire des calculs.

    merci

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Si tu travailles en mode 32 bits, c'est malheureusement normal: la limite de mémoire adressable dans ce mode étant de 2GB.

    Si cela t'est possible, essaye de passer en mode 64 bits, mais tu finira malgré tout tôt ou tard par observer un ralentissement du fait de la monopolisation de la mémoire disponible.

    Une solution que l'on pourrait envisager, en partant du principe que tu ne dois jamais disposer, à un moment T, de 10^9 éléments dans ton tableau, serait de sauvegarder dans un fichier les éléments calculés "inutiles" au calcul de manière à ne garder qu'un nombre finalement très restreint de résultat.

    Une fois que tu a atteint le nombre d'éléments que tu voulais calculer, tu utiliserais le fichier pour les récupérer et pouvoir les manipuler "plus en profondeur".
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    ok, mais il faut a ce moment la plusieurs fichiers,
    et l'accès au fichier doit être super long.


    de plus, quand tu as un fichier .txt qui contient des valeurs disposées en colonne, comment tu fais pour acceder directement à une ligne?

    merci

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    On n'utilise pas un fichier texte pour faire du swap.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    C'est quoi du swap?

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    C'est critique? Sinon t'as STXXL qui pourrait te convenir. (il me semble que quelques benchs ont été réalisée sur le forum il y'a un petit moment).
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par deubelte Voir le message
    ok, mais il faut a ce moment la plusieurs fichiers,
    et l'accès au fichier doit être super long.
    Un seul fichier peut suffire, tant que tu n'atteins pas la limite de taille imposée par ton OS à ce sujet
    de plus, quand tu as un fichier .txt qui contient des valeurs disposées en colonne, comment tu fais pour acceder directement à une ligne?

    merci
    N'utilise pas un fichier texte, mais bien un fichier binaire

    Tu auras la certitude que, si ton fichier contient des éléments de type double, il seront tous codés sur un même nombre d'octets (typiquement sizeof(double) ).

    Un calcul simple te permet d'accéder à n'importe quel élément très facilement à l'aide de la fonction membre seekg (ifs.seekg(sizeof(double)*numero_element,ios_base::beg) )

    Un seul fichier peut suffire, tant que tu n'atteint pas les limites imposées par ton OS ou ton système (un fichier de 3 Tb, sur un disque de 1, ca va pas le faire )

    Si même, de par les restrictions de l'OS, tu ne peux envisager de créer un fichier de plus de 4Gb, qu'à cela ne tienne:

    Tu crées une succession de fichiers contenant au maximum un nombre fixe d'éléments (par exemple: 100 000 000)

    Tu obtient donc, pour tout N étant le nombre d'éléments que tu dois calculer, (N / 100 000 000 ) +1 fichiers (que tu prend la peine de nommer de manière incrémentale) dont le dernier contient N % 100 000 000 d'éléments.

    Lorsque tu dois récupérer l'élément numéro X, tu ouvre le fichier nom_du_fichier(X/ 100 000 000).dat et tu va chercher l'élément se trouvant en position (X% 100 000 000) dans le fichier

    Bien sur, ces lectures et écritures seront de nature à ralentir l'accès au données, mais, sur un nombre aussi élevé de valeur à gérer, cela reste un moindre mal
    Citation Envoyé par Médinoc Voir le message
    On n'utilise pas un fichier texte pour faire du swap.
    C'est deubelte qui a parlé d'un fichier texte
    Citation Envoyé par deubelte Voir le message
    C'est quoi du swap?
    Sous linux, le swap est la mémoire virtuelle, représentée par une partition bien particulière.

    Pris dans ce sens, le but du swap est de permettre de placer des informations "en dehors de la RAM" (autrement dit dans un fichier) de manière à la récupérer en temps opportun.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    N'utilise pas un fichier texte, mais bien un fichier binaire
    Comment tu fais pour créer un fichier binaire? C'est un .dat?

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par deubelte Voir le message
    Comment tu fais pour créer un fichier binaire? C'est un .dat?
    En fait, l'extension est simple question de gout... j'ai utilisé ".dat" simplement parce que cela fait référence à ... data

    Pour ouvrir un fichier en mode "binaire" (terme très mal choisi s'il en est), il suffit de passer std::ios_base::binary en deuxième argument lors de l'ouverture du fichier.

    Cela donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    /* pour lire un fichier binaire */
    std::ofstream ofs("fichier.dat",std::ios_base::binary);
    /* pour écrire dedans */
    std::ifstream ifs("fichier.dat",std::ios_base::binary);
    Fais cependant attention au fait qu'il ne faut pas utiliser les opérateurs << et >>, mais les fonctions respectives read (pour la lecture) et write (pour l'écriture)

    Fais aussi attention au fait que tu peux éprouver des problèmes au niveau de la compatibilité entre les différents systèmes (selon le boutisme et la taille des types primitifs)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    ok, j'ai essayé tout ca, ca me semble fonctionner.

    j'ai quelques questions:
    quand j'utilise la fonction
    ca plante, il faut que j'utilise qqch comme:
    n'y a t il pas un moyen définitif pour eviter ce genre de bug.
    j'avais vu qqch comme: pow(10,8f), f pour désigner float..
    je ne m'en rappelle plus exactement

    Autre question:
    Dans cette page d'explication,
    http://www.cplusplus.com/reference/i.../istream/read/

    on a l'explication:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    istream& read ( char* s, streamsize n );
    cela signifie que read renvoie un objet de type pointeur sur istream?

    Si on fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    istream *m;
    m=read(.....);
    à quoi sera égale *m?

    merci

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    read() ne renvoit pas un pointeur, mais une référence sur l'objet lui-même.

    En clair, tu peux faire ceci:
    is.read( ... ).read( ... ).read( ... )
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Sa renvoie une référence sur *this; Sa permet de faire du chainage d'appel.


    grillé
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  13. #13
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Dans ce cas là, c'est quoi *this?
    c'est bien un point this que je sache

  14. #14
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Autre chose:
    dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ofs.read(reinterpret_cast<char*>(&xin), sizeof(double));
    tu as:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    reinterpret_cast<char*>
    Cela permet de covnertir un char en int (ou double...)?

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Bas this c'est un pointeur sur l'instance courante. Donc *this; c'est le pointeur déréférencé (ie l'objet).

    Pour le reinterpret_cast<T>(x) ça converti x en T. Mais ça veut dire au compilo : toi tu comprends pas pourquoi mais moi je sais ce que je fais, alors laisse moi le faire.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  16. #16
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Pour le reinterpret_cast, c'est ce que dit Goten, c'est à dire que ça doit être utilisé quand on sait exactement ce qu'on fait et ce qu'on veut.

    En gros, quand tu utilises des cast, il y a une conversion implicite qui est effectuée.

    Un entier n'est pas codée de la même manière qu'un float, ou un double. Et lorsque tu fais, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float a = 1.2f;
    int b = static_cast< int > ( a );
    a et b n'auront pas la même représentation dans la mémoire. Cependant, si tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char a[4] = { 0x00, 0x00, 0x00, 0x01 };
    int b = *reinterpret_cast< int* >( &a );
    Là, a et b auront la même représentation en mémoire, soit la même suite de 32 bits, bien que comme tu vois, programmatiquement parlant, ils sont pas du tout pareil.

    Ca fait ce que ça dit: ça prend une zone mémoire et ça l'interprète de la manière que tu veux qu'il l'interprète. Attention cependant, Si tu changes tes données sérialisées de plateforme, le résultat peut ne pas être celui attendu, car différentes plateformes peuvent encoder leurs données de différentes manières (Little Endian / Big Endian). Si tu veux donc faire quelque chose de portable, il faut que tu passes tout en un codage ou un autre. htons/ntohs sont là pour t'aider.

    C'est surtout utilisé pour de la sérialisation, ce qui est un peu ce que tu fais ici.

  17. #17
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par JulienDuSud Voir le message
    htons/ntohs sont là pour t'aider.
    Pour une sérialisation binaire, je préfère généralement écrire moi même octet par octet. C'est d'ailleurs quasiment le seul code où j'utilise les opérateurs bit à bit. sachant qu'il n'y a pas que le boutisme qui peut différer (long, c'est 32 ou 64 bits ?, par exemple)
    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.

  18. #18
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Pour une sérialisation binaire, je préfère généralement écrire moi même octet par octet. C'est d'ailleurs quasiment le seul code où j'utilise les opérateurs bit à bit. sachant qu'il n'y a pas que le boutisme qui peut différer (long, c'est 32 ou 64 bits ?, par exemple)
    Ah c'est sûr, j'ai bien dit que c'était là pour aider seulement ^^.

    Sans oublier que pour toute sérialisation qui se respecte, la taille des types doit être prédéfini et non dépendant du système/compilateur.
    Personellement j'ai défini mes types (u)int8, (u)int16, (u)int32, (u)int64 avec, en mode debug un assert( sizeof(type) == taille_attendue ), comme ça y a aucune ambiguité

  19. #19
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    pourquoi ne pas utiliser SQLite?

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/09/2007, 14h45
  2. Augmenter le nombre de fenêtres dans tous les programmes xp
    Par pierrot67 dans le forum Windows XP
    Réponses: 2
    Dernier message: 17/07/2007, 12h19
  3. Réponses: 3
    Dernier message: 04/10/2005, 15h13
  4. Compter le nombre d'élément dans un tableau
    Par cryptorchild dans le forum Langage
    Réponses: 6
    Dernier message: 08/07/2005, 13h01
  5. Comparaison de base et calculs du nombre d'éléments dans Bas
    Par BXDSPORT dans le forum Bases de données
    Réponses: 3
    Dernier message: 19/07/2004, 08h00

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