[C++] Problème allocation (besoin de 100Go de RAM !)

Problème allocation (besoin de 100Go de RAM !) [C++] - C++ - Programmation

Marsh Posté le 14-12-2006 à 17:26:42    

Bonjour à tous.
 
Alors pour vous expliquer brievement mon problème, j'aimerais représenter une surface en OpenGL qui serait carrée et comporterait sur chaque côté 10 000 points.
Le problème n'est absolument pas d'ordre OpenGL je l'évoque juste pour situer le contexte.
 
J'ai donc créer une classe Point, qui contient 3 int et quelques méthodes, une classe Surface qui contient une liste des points et le constructeur de cette classe se charge de créer mes Points tous à (0,0,0) au début.
 
Le problème : j'arrive jamais à passer la création de ma surface car ca pète avant pour me dire que j'ai pu de mémoire de disponible. J'ai pourtant regarder plusieurs fois mon code sans arriver à voir ou ca merde (ca merde peut être pas remarque je fais peut être un truc pas top ^^).
 
Alors j'en appelle à vous pour me dire si il y a dans mon code une grosse bourde que je n'aurais pas vu  :sweat: ou si il faut que je change de technique (j'aimerais bien que vous en ayez une à me proposer car là comme ca je vois pas trop).
 
Je vous met la description de mes classes, je vous met pas les .cpp je vous met juste ce qui est interessant, et un main minimaliste (oui il n'y a pas de désallocation à la fin du main j'en suis conscient c'est pas bien etc etc ... )

Code :
  1. // point.h
  2. class Point
  3. {
  4. public:
  5. Point(); // Initialise a 0 x, y et z
  6. Point(int n); // Initialise x y et z à n
  7. Point(int x, int y, int z); // Initialise x y et z selon les paramètres
  8. // Permet de set les variables
  9. void SetX(int val);
  10. void SetY(int val);
  11. void SetZ(int val);
  12. void SetCoord(int x, int y, int z);
  13. // Retourne la valeur des variables
  14. int  GetX();
  15. int  GetY();
  16. int  GetZ();
  17. int*  GetCoord();
  18. private:
  19. int x, y, z;
  20. };


Code :
  1. // surface.h
  2. class Surface
  3. {
  4. public:
  5. Surface();
  6. void Display(); // Affichage de la surface
  7. int AddPoint(std::string str); // Ajout d'un point dans la liste (str sous la forme (x,y,z) )
  8. private:
  9. std::vector<Point*> pList;
  10. };


Code :
  1. // Constructeur de Surface
  2. Surface::Surface()
  3. {
  4. std::cout << "Loading..." << std::endl;
  5. for (int i = 0; i < 10000; ++i)
  6. {
  7.  for (int j = 0; j < 10000; ++j)
  8.  {
  9.   Point *newPoint = new Point(j, i, 0);
  10.   this->pList.push_back(newPoint);
  11.  }
  12.  std::cout << "\r" << i / 100 << "%";
  13. }
  14. }


Code :
  1. // main.pp (minimaliste)
  2. #include "surface.h"
  3. int  main(int argc, char *argv[])
  4. {
  5.     Surface*   mySurface = new Surface;
  6.     std::cout << "Surface créée" << std::endl;
  7.     return 0;
  8. }


(avec ceci normalement c'est pas compilable, mais vous pouvez virer tout ce qui est inutilisé si vous voulez essayer de compiler)
 
Si vous vous demander pourquoi un vector ? Bah en fait je me sert de celui ci pour sa méthode at() . Je me suis d'ailleurs demandé si le problème pouvait venir de celui-ci mais j'ai pas testé en utilisant autre chose.

Reply

Marsh Posté le 14-12-2006 à 17:26:42   

Reply

Marsh Posté le 14-12-2006 à 17:51:04    

Salut,
 
   Bon, j'ai pas essayé mais vu ce que tu cherche a faire ça m'étonne pas que tu ais un problème de mémoire. franchement, as-tu vraiment besoin d'avoir tes 10000*10000 points en même temps en mémoire ? A mon avis c'est a toi de déterminer quels seront les points dont tu as immédiatement besoin, qui seront conservé dans la RAM et les autres, que tu chargeras que quand tu en auras besoin. Par ce que la je suis quasiment sur que le problème c'est plutôt ton algo pour l'affichage qui est le réel problème. Essaye de regarder du côté des arbres BSP par exemple, ou d'autres truc du genre...
 
   Sinon, une petite remarque : moi j'aurais pas fait un vector de pointeur sur des Point mais plutôt, un vector de Point... (enfin peut-être a tord...)

Reply

Marsh Posté le 14-12-2006 à 17:54:19    

çà te fait quand meme un vector de ... 100000000 points ! soit, si l'on oublie tout le reste qu'un seul point doit occuper en mémoire pour exister, 300000000 entiers ! soit si les int sont sur 4 octets (pas sur), 1200000000 octets, don cà peu près 1144mo de mémoire ! rien d'anormal donc...
 
 
P.S : çà resoudra pas le problème, mais si çà marche
 

Code :
  1. this->pList.push_back(new Point(j, i, 0));


 
serait mieux niveau perfs et occupation mémoire que :
 

Code :
  1. Point    *newPoint = new Point(j, i, 0);
  2. this->pList.push_back(newPoint);


 
mais du coup c'est un Vector de Point et plus de pointeurs....

Message cité 1 fois
Message édité par remiworld le 14-12-2006 à 17:56:44
Reply

Marsh Posté le 14-12-2006 à 18:02:23    

Pour l'affichage je comptais simplement dessiner des plans à l'aide des coordonnées de mes points.
 
Donc je prend les points 1 et 2 des lignes 1 et 2 et je trace un plan. Je prend les points 2 et 3 des lignes 1 et 2 et je trace un plan etc.
Arrivé au bout des lignes je fais pareil avec les lignes 2 et 3 etc.
 
Bon je vais donc chercher un moyen de ne pas charger chaque point.

Reply

Marsh Posté le 14-12-2006 à 18:07:31    

  Ben, si c'est que des plans que tu veux afficher. tu peux essayer une interpolation polynomiale de tous tes points. ça te permettrais de ne pas a avoir a stocker tous tes points. ça peut toujours être une méthode. Ou plus simplement déterminer quels sont les points qui sont dans le champ de vision et n'afficher que ceux la...
   Enfin, je crois que le problème viens plutôt de là...

Reply

Marsh Posté le 15-12-2006 à 09:26:12    

J'ai déjà commencé à travailler sur un moyen de ne pas charger en mémoire tous les points. En fait j'aimerais chargé le minimum, et en calculer certains à la volée lorsque je vais placer mes plans. je trace mon plan et là je supprime mon point. Je suppose que ca peut marcher. Si quelqu'un pense que non, qu'il n'hésite pas à le dire histoire que je fasse pas plein de trucs pour rien.
 
Ta remarque sur l'interpolation polynomiale me parait interessante. Si la première méthode ne fonctionne pas j'essayerai de me pencher sur celle-ci.
 
En tout cas, merci à vous deux pour votre aide. et vos propositions comme solutions alternatives.

Reply

Marsh Posté le 15-12-2006 à 09:59:10    

déjà, soit travaille avec des Point et pas des Point* ou alors utilise un véritable allocateur mémoire. Sinon utilise une matrice creuse.

Reply

Marsh Posté le 15-12-2006 à 12:45:10    

matrice creuse + pré-allocateur statique avec un new de placement.
Ca se google bien tout ça

Reply

Marsh Posté le 21-12-2006 à 22:59:01    

Si tes coordonnees ne depassent jamais 65535, declare les plutot de type "unsigned short int" a la place de "int". Tu diminueras deja ta memoire de moitie...
 
En plus de ca, z semble etre toujours a 0, donc pourquoi ne pas supprimer la variable 'z', et faire retourner 0 a ta methode: GetZ(){ return 0; }
Tu diviserais encore ta memoire par 10000...
 
Avec ces 2 changements tu n'occuperais plus que 572Mo a la place de 10.9To! (ce qui devrait rentrer)..

Message cité 1 fois
Message édité par nickman le 21-12-2006 à 23:13:12
Reply

Marsh Posté le 21-12-2006 à 23:00:43    

remiworld a écrit :

çà te fait quand meme un vector de ... 100000000 points ! soit, si l'on oublie tout le reste qu'un seul point doit occuper en mémoire pour exister, 300000000 entiers ! soit si les int sont sur 4 octets (pas sur), 1200000000 octets, don cà peu près 1144mo de mémoire ! rien d'anormal donc...
 
 
P.S : çà resoudra pas le problème, mais si çà marche
 

Code :
  1. this->pList.push_back(new Point(j, i, 0));


 
serait mieux niveau perfs et occupation mémoire que :
 

Code :
  1. Point    *newPoint = new Point(j, i, 0);
  2. this->pList.push_back(newPoint);


 
mais du coup c'est un Vector de Point et plus de pointeurs....


 
Ca ne ferra aucune difference niveau occupation de memoire, et c'est toujours un vecteur de "pointeurs de point" et non un vecteur de points.
 
Autre remarques: Mes calculs donnent plutot : (10000^3) * 3 * 4 = 12000000000000 = 10.9To! donc il y a bien quelque chose d'anormal.

Message cité 1 fois
Message édité par nickman le 21-12-2006 à 23:07:13
Reply

Marsh Posté le 21-12-2006 à 23:00:43   

Reply

Marsh Posté le 22-12-2006 à 21:11:58    

nickman a écrit :

Ca ne ferra aucune difference niveau occupation de memoire, et c'est toujours un vecteur de "pointeurs de point" et non un vecteur de points.


 
Cela évite toujours la création d'un Point pour tout de suite après le copier... : il est créé directement de façon a etre "passé" au push_back. Comme je l'ai dit, c'est sur que çà ne changera pas grand chose, et surtout çà ne résoudra pas le prob.
 

nickman a écrit :


Autre remarques: Mes calculs donnent plutot : (10000^3) * 3 * 4 = 12000000000000 = 10.9To! donc il y a bien quelque chose d'anormal.


 
Pourquoi "^3" ?

Reply

Marsh Posté le 23-12-2006 à 10:58:27    

Coucou. Pour commencer, désolée pour le temps de réponse.
 

Taz a écrit :

déjà, soit travaille avec des Point et pas des Point* ou alors utilise un véritable allocateur mémoire. Sinon utilise une matrice creuse.


En fait j'avais tendance en C à tout allouer avec malloc (mes structures et compagnie) donc j'ai encore ce genre de "reflexes". Pourquoi vaut-il mieux travailler sur des Point directement ? En C on me disait qu'il vallait mieux allouer tout ce qui est genre structure à l'aide de malloc. J'en suis qu'a mon 1er mois de C++ désolée si la question peut paraitre idiote.
 

Joel F a écrit :

matrice creuse + pré-allocateur statique avec un new de placement.
Ca se google bien tout ça


Vu que vous êtes 2 à en parler, je vais regarder en quoi ca consiste.
 

nickman a écrit :

Si tes coordonnees ne depassent jamais 65535, declare les plutot de type "unsigned short int" a la place de "int". Tu diminueras deja ta memoire de moitie...
 
En plus de ca, z semble etre toujours a 0, donc pourquoi ne pas supprimer la variable 'z', et faire retourner 0 a ta methode: GetZ(){ return 0; }
Tu diviserais encore ta memoire par 10000...
 
Avec ces 2 changements tu n'occuperais plus que 572Mo a la place de 10.9To! (ce qui devrait rentrer)..


En fait je cherche à représenter une surface donc tu te doutes bien que c'est une surface non-plane. Donc j'initialise tous mes points à z = 0 mais après évidement certains vont être modifiés.


Message édité par Helena le 23-12-2006 à 11:00:32
Reply

Marsh Posté le 23-12-2006 à 14:22:17    

le tout malloc c'est catastrophique dans ce cas. Surtout quand un point ne fait certainement qu'une douzaine d'octets. La sémantique par valeur ici a sans doute bien plus d'avantage.

Reply

Marsh Posté le 23-12-2006 à 18:55:34    

modélisation bancale.
 
c'est quoi la nature de tes données ?

Reply

Marsh Posté le 23-12-2006 à 20:56:55    

Helena a écrit :

Bonjour à tous.
 
Alors pour vous expliquer brievement mon problème, j'aimerais représenter une surface en OpenGL qui serait carrée et comporterait sur chaque côté 10 000 points.
Le problème n'est absolument pas d'ordre OpenGL je l'évoque juste pour situer le contexte.

Salut,
 
je réfute fermement cette proposition :whistle:  
 
http://www.opengl.org/documentation/specs/
 
Pour créer une surface faut d'abord créer une fenêtre d'appli et y attacher une scène OpenGL, puis créer un objet (la surface 2D, ici un carré) et lui assigner des vertex 2D, des points quoi, 4 ça suffit amplement. Après tu rends le tout, l'utilisation d'un bavoir est d'ailleurs fortement conseillée lors de cette étape.

Reply

Marsh Posté le 23-12-2006 à 21:29:43    

le problème c'est qu'il faudrait savoir ce qu'elle veut.
 
on sait pas si son 10000x10000 c'est une heightmap ou un truc irrégulier au niveau adressage et qui peut pas être mis en oeuvre comme surface 2d où t'as pas besoin de stocker les coordoonées 2D par élément.
 
c'est pour ça que déjà sa modélisation me parait bizarre.

Reply

Marsh Posté le 23-12-2006 à 22:49:23    

Bin en fait je veux modéliser une surface de 10000 par 10000 "Point" et j'ai certains points dont j'ai les coordonnées dans un fichier texte.
 
La en ce moment même j'ai abandonné l'idée de tout stocker en mémoire donc oui en effet LKoLRn je trace un carré de 4 points ca suffit amplement mais c'est pas une surface ca c'est un pauvre carré.
 
Donc maintenant faut que j'arrive à faire passer cette surface par un certains nombre de points connus.

Reply

Marsh Posté le 23-12-2006 à 22:50:45    

tu veux faire quoi un nurbs ?
pour représenter quoi ? un terrain ? une pièce cao ? une voile de bateau ?


Message édité par bjone le 23-12-2006 à 22:51:30
Reply

Marsh Posté le 24-12-2006 à 03:31:38    

Euh, dsl j'ai lu de biais, ce qui n'est pas très pratique pour comprendre... Effectivement on est encore loin d'avoir besoin d'OpenGL.
 
En fonction des points connus de ton fichier il faut déterminer le polynôme d'interpolation unique qui te donnera tous tes z, c'est bien ça ?
Si oui il faut donc bien aboutir à une heightmap, seulement ça fait beaucoup trop de points pour être calculé dans des temps réalistes...
 
Ya des méthodes de calcul matriciel pour simplifier toussa, diagonalisation, Lagrange, encore plein d'autres que je connais po... (les mathématiciens sont pleins de ressources, et me souviens de rien ou presque). Tu es en licence math-info non ?
 
Sur cette partie purement nanalytique tu as déjà des résultats ? Utilises-tu MAtLab ? Ya des tas de fonctions déjà codées qui j'en suis sûr te permettront de résoudre au moins partiellement ton problème des z.
 
Sinon sous OpenGL ça donne quoi ? Tun comptes rendre ça comment ? (perso une vue du dessus me paraît des plus intéressantes... :whistle:)

Reply

Marsh Posté le 24-12-2006 à 10:40:20    

Sinon si ta structrue de Poitn est rikiki en terme d'occupation méméoire, y a peut être à creuser du coté du SmallObjectAllocator de Alexandrescu.

Reply

Marsh Posté le 24-12-2006 à 17:04:47    

Helena a écrit :

Bin en fait je veux modéliser une surface de 10000 par 10000 "Point" et j'ai certains points dont j'ai les coordonnées dans un fichier texte.

 

La en ce moment même j'ai abandonné l'idée de tout stocker en mémoire donc oui en effet LKoLRn je trace un carré de 4 points ca suffit amplement mais c'est pas une surface ca c'est un pauvre carré.

 

Donc maintenant faut que j'arrive à faire passer cette surface par un certains nombre de points connus.


Le jeu des devinettes, ca va un temps. Tant que tu n'auras pas precise ce que tu veux faire exactement, personne ne pourra t'aider.
C'est quoi l'application ? Quelles sont les contraintes ? bjone a pose des questions precises.


Message édité par el muchacho le 24-12-2006 à 17:06:50
Reply

Marsh Posté le 28-12-2006 à 14:52:08    

remiworld a écrit :

Cela évite toujours la création d'un Point pour tout de suite après le copier... : il est créé directement de façon a etre "passé" au push_back. Comme je l'ai dit, c'est sur que çà ne changera pas grand chose, et surtout çà ne résoudra pas le prob.


 
Bah ? :heink:
 
Ca ne change même absolument rien, ton Point n'est pas copié dans la seconde version [:spamafote]

Reply

Marsh Posté le 04-01-2007 à 10:22:26    

Au passage, ca fait bien 100000000 points mais il manque alors 100000000 delete !!!

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed