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 :

Gestion avancée de la mémoire


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut Gestion avancée de la mémoire
    Bonjour,

    Je me heurte à un probleme de gestion mémoire.
    Rien de nouveau en C++ me direz vous, mais néanmoins...

    Contexte :
    Sur le projet que je developpe, on utilise des modeles objets plutot lourds, des libraires externes, etc... du bon gros projet de 120k lignes en somme.

    Le soucis c'est qu'a présent, les données utilisées/generées (ex: graphe de scene) sont tellement devenues imposantes que la mémoire sature rapidement, déclenchant des magnifiques crash.
    Je cherche donc un moyen de gerer les allocations mémoire pour éviter ou tout du moins limiter la portée des crash.
    De ce que j'ai vu/lu les operateurs new levent des exception std::bad_alloc si necessaire, sans pour autant retourner NULL.

    Ce que je voudrais éviter c'est de devoir encadrer chaque new par un manager d'exception (bloc try...catch).
    Un seul bloc pourrait faire l'affaire s'il est placé à haut niveau, en tout cas je pense, mais la complexité est telle qu'il n'est pas évident de localiser le bon endroit pour le placer.

    Ma question est donc de savoir si le fait de placer un seul bloc (ou une poigné) à haut niveau dans le code (par haut niveau j'entend le main() ou les méthodes principales) pourrait suffire à gerer les crash.
    D'autre part, le catch permettra de ne pas crasher l'application, mais l'état des elements alloués en mémoire à ce moment ne sera selon moi pas connu, et donc il sera difficile de continuer l'execution du programme.

    Il y a aussi la possibilité de surcharger/redéfinir l'operateur new, mais je doute que celà aide...

    Voilà j'espere etre resté compréhensible, si ce n'est pas le cas n'hesitez pas à demander des clarifications.

    Merci de votre aide.

  2. #2
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Ange_blond Voir le message
    Bonjour,
    Ce que je voudrais éviter c'est de devoir encadrer chaque new par un manager d'exception (bloc try...catch).
    Je te conseille en effet d'éviter ça !

    Ma question est donc de savoir si le fait de placer un seul bloc (ou une poigné) à haut niveau dans le code (par haut niveau j'entend le main() ou les méthodes principales) pourrait suffire à gerer les crash.
    Tu réponds tout seul à ta question : attraper une exception, c'est bien. La traiter c'est super. Mais continuer ton programme c'est une autre paire de manche. Surtout que recevoir une std::bad_alloc, ça ferme un peu le bal, car si l'utilisateur voulait vraiment faire ça, bah que peut il faire d'autre ?


    Il y a aussi la possibilité de surcharger/redéfinir l'operateur new, mais je doute que celà aide...
    Pour trouver qui a lancé et où si, mais à part ça...
    http://loulou.developpez.com/tutorie.../partie1/#L2.2

    Au final, tu devrais peut-être prendre un profiler et déterminer comment réduire ton empreinte mémoire, si besoin en diminuant l'optimisation. Réécrire les parties concernées ensuite ?
    Ou alors prendre un PC plus musclé !

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Tu peux aussi jeter un coup d'oeil à set_new_handler().

    Il y a des merveilles qu'on ne devrait pas cacher...

    En gros, un handler est appelé chaque fois qu'une allocation échoue. Il peut ainsi libérer de la mémoire, et redonne le contrôle a new qui recommence, etc.

    Bien évidemment, il y a un mécanisme d'arrêt parce que sinon, tu aurais bien des difficultés à sortir d'une telle boucle
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 117
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Et si la surcharge de l'opérateur new vous permettez de renvoyer NULL lors d'un échec, est ce que cela peut convenir ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Salut

    As tu passé un coup de Valgrind sur ton projet, pour vérifier si ça ne fuit pas un peu partout ? Dans un projet comme ça, de petites fuites locales avoir un effet désastreux si elles se retrouvent dans des boucles.

  6. #6
    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
    Citation Envoyé par poukill Voir le message
    Pour trouver qui a lancé et où si, mais à part ça...
    http://loulou.developpez.com/tutorie.../partie1/#L2.2
    Attention : J'ai déjà signalé que ce code était non conforme, puisqu'il fait un #define sur un mot clef, mais ce problème n'est plus depuis peu un problème purement théorique. En C++0x (et contre mon vote), il est actuellement prévu que le mot clef new soit réutilisé dans un autre contexte où ce #define ne passera pas. Donc ce code ne pourra pas compiler de code C++0x.
    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.

  7. #7
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Salut

    As tu passé un coup de Valgrind sur ton projet, pour vérifier si ça ne fuit pas un peu partout ? Dans un projet comme ça, de petites fuites locales avoir un effet désastreux si elles se retrouvent dans des boucles.
    Oui ça a été fait.
    Mais le programme n'a pas(peu) de fuites. Il s'agit réellement d'un consommation énorme parce qu'il doit gerer des masses de données, et sans cesse allouer/désalouer de la mémoire pour les afficher...

    Citation Envoyé par LittleWhite Voir le message
    Bonjour,

    Et si la surcharge de l'opérateur new vous permettez de renvoyer NULL lors d'un échec, est ce que cela peut convenir ?
    J'y avais pensé oui, mais il faudrait tout de meme tester tous les new pour savoir si ça a échoué ou non, ce qui revient à coller des try catch partout au final.

    Citation Envoyé par Emmanuel Deloget Voir le message
    Tu peux aussi jeter un coup d'oeil à set_new_handler().

    Il y a des merveilles qu'on ne devrait pas cacher...
    Je jette un oeil de ce pas merci. je ne connaissais pas mais ça pourrait s'avérer utile

    Citation Envoyé par poukill Voir le message
    Tu réponds tout seul à ta question : attraper une exception, c'est bien. La traiter c'est super. Mais continuer ton programme c'est une autre paire de manche. Surtout que recevoir une std::bad_alloc, ça ferme un peu le bal, car si l'utilisateur voulait vraiment faire ça, bah que peut il faire d'autre ?
    Je vais tester une gestion qui va fermer le programme dans les regles, ou tout du moins éviter le crash à venir apres un bad_alloc.
    Ce que je recherche c'est avant tout de la stabilité.

    Citation Envoyé par poukill Voir le message
    Au final, tu devrais peut-être prendre un profiler et déterminer comment réduire ton empreinte mémoire, si besoin en diminuant l'optimisation. Réécrire les parties concernées ensuite ?
    Ou alors prendre un PC plus musclé !
    Alors réécrire le code en quelques jours ça risque d'etre chaud
    Et changer de PC... ben faut le dire au client mais j'arrete pas de le rabacher depuis 2 ans

    Merci pour vos conseils, je vais continuer à creuser la question.
    N'hesitez pas si vous avez encore des idées

  8. #8
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Si tu as beaucoup de données, peut-être peut tu tout simplement écrire un adapteur qui va en garder une grosse partie sur disque en attendant de t'en servir pour de vrai. Si c'est possible, il serait sage de combiner cette approche avec une notion de niveau de détails (premier niveau : pas beaucoup de données, mais une approximation de la totalité des données ; les niveaux en dessous sont de plus en plus détaillés ; voir ce qui se fait en mip mapping pour les jeux vidéo).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  9. #9
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Si tu as beaucoup de données, peut-être peut tu tout simplement écrire un adapteur qui va en garder une grosse partie sur disque en attendant de t'en servir pour de vrai. Si c'est possible, il serait sage de combiner cette approche avec une notion de niveau de détails (premier niveau : pas beaucoup de données, mais une approximation de la totalité des données ; les niveaux en dessous sont de plus en plus détaillés ; voir ce qui se fait en mip mapping pour les jeux vidéo).
    C'est à dire que... c'est dejà le cas !
    J'utilise des LOD qui sont paginé sur le disque et qui sont chargé depuis le disque à la runtime, et sont déchargé aussi à la runtime. (en fonction de la camera)
    C'est ceci qui implique des mouvements massifs d'allocation/désallocation à la runtime et qu'il faut gerer car n'importe quand un gros paquet de données peut etre alloué ou désaloué.

    Sans ce systeme de LOD, ça ferait longtemps qu'on aurait cessé d'essayé de charger autant de données

  10. #10
    screetch
    Invité(e)
    Par défaut
    le problème peut être que tes objets ont tous des tailles différentes, et que tu peux en mettre n'importe ou. C'est pour un jeu vidéo donc?

    il existe d'autres possibilités de stockage qui permettent de charger et decharger plus "amicalement":

    mettons que tu reserves de base un enaaaaurme bout de mémoire (pas trop hein )
    ton "monde" (la liste des objets) est divisé ensuite en couches:
    la couche 0 est ce qui est visible en permanence
    la couche 1 est divisée en case; elle n'est chargée que si on est proche de cette case
    la couche 2 itou, cases plus petites.
    Les lods les plus precis sont donc dans la couche 2, la couche 0 contient les objets les plus imprécis

    lorsque la caméra est en un point x, y: tu charges (de base) la couche 0, et tu la mets tout au debut de ta memoire
    tu determines ensuite sur quelle "case" tu es, tu risques d'avoir besoin des cases alentours évidemment (donc mettons 9 cases de couche 1: la case sur laquelle tu es et les 8 cases autour). Tu les charges. Puis de même avec les 9 cases de couche 2.
    Lorsque tu te deplaces, tu devras donc decharger certaines cases de couche 1 et 2 pour les remplacer par d'autres. L'astuce est alors souvent de faire des cases qui ont pratiquement le même cout; alors on vide une case dont on a pas besoin et on la remplace par une case dont on va avoir besoin.

    Ca peut etre lourd si tu changes en permanence de case genre tu te promènes juste sur la frontière. Dans ce cas, il se peut que tu doives decharger les cases dont tu n'as plus besoin mais... que tu ne charge pas toujours les cases dont tu vas avoir besoin, tant que tu n'es pas sur que tu vas vraiment t'en servir.

    Il faut donc gérer tes données par batch, pas individuellement, et tu charges tout d'un coup, pas un par un. Et pour ce faire tu peux utiliser les mêmes blocs de mémoire.
    Si une case ne tient pas en mémoire c'est que la case est trop gourmande, il faut la retravailler (je part du principe d'un jeu vidéo ou on a le choix, hein, donc si tu n'as pas le choix pour une raison x ou y ca va être cotton).

Discussions similaires

  1. Gestion avancée d'exception et compatibilité dotnet
    Par RamDevTeam dans le forum Delphi .NET
    Réponses: 1
    Dernier message: 14/11/2005, 18h12
  2. Réponses: 24
    Dernier message: 30/10/2005, 09h27
  3. Réponses: 2
    Dernier message: 15/09/2005, 15h08
  4. [QuickReport] Gestion avancée des imprimante ?
    Par portu dans le forum Langage
    Réponses: 2
    Dernier message: 14/09/2005, 10h55
  5. Concilier gestion avancée de vertices et API OpenGL
    Par GaldorSP dans le forum OpenGL
    Réponses: 4
    Dernier message: 30/08/2005, 13h11

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