je sais que le titre est vague, mais bon, je n'ai pas trouvé mieux...
Dans le cadre d'un projet perso, je me suis retrouvé à écrire une classe qui encapsule la notion que khronos appelle VkBuffer. Grosso modo, cette classe (celle que j'ecris) fonctionne un peu comme std::vector (ou tout autre tableau de manière génerale): On peut ajouter, supprimer, deplacer son contenu.
Mon problème apparait lorsqu'il s'agit de depacer un seul élement d'une memoire à une autre; typiquement de la RAM vers la VRAM. Ce deplacement à pour effet de créer un "trou" dans le buffer d'origine.
Ma question est donc est-ce à la classe de supprimer et combler implicitement ce trou, ou est-ce à l'utilisateur de le faire? Au depart, je me suis dis que personne ne veut se balader avec un buffer ayant des "trous" de gauche à droite et donc que c'est à la classe de supprimer et combler les trous de manière systèmatique et implicite. Seul bèmol, je suis arrivé sur une sorte de récursion infinie du genre:
Une des solutions pour éviter cette situation serait de dissocier les notions "deplacer un contenu" et "supprimer une place vacante". Comme je l'ai dit plus haut, personne n'aime les places vacantes... Du coup je suis un peu bloqué...
Est ce que l'ordre de ton tableau a une importance ?
S'il n'en a pas, pour supprimer un élément au milieu il existe un truc diablement efficace : tu swap l'élément que tu veux supprimer avec le dernier élément de ton vector, puis tu pop-back.
cette astuce ne marche que si ces 2 élements font exactement la même taille. Dans mon cas, c'est impossible de savoir à l'avance.
J'ai une (ou plusieur en fonction du type de mémoire) plage de memoire "brute" fixe, disons de 0 à 207MB. C'est à moi de m'organiser pour savoir que la sous-plage 0-1ko correspond à telle donnée ou celle de 5ko à 50ko correspond à une autre par exemple.
Si jamais il n'y a "rien" dans la sous plage 1ko-5ko, c'est soit je la reserve pour de prochaines données qui feront très exactement 4ko, soit je deplace tout ce qui suit. Du genre la sous plage 5ko-50ko sera desormais 1ko-46ko.
Après le problème ne vient pas vraiment de là, mais plutôt de savoir si c'est à l'utilisateur de la classe de faire cette optimisation de mémoire en connaissance de cause ou c'est à la classe de la faire de manière systématique...
En sachant que j'ai trouvé une solution à la recursion infinie d emon premier post. Du coup la question reste maintenant purement d'un point de vue conception.
Tu as une solution qui est de dissocier, Le stockage de l'accès en passant par un allocateur dédié. L'idée, c'est que tu assures la contiguïté au niveau de l'allocateur au lieu de l'assurer au niveau du conteneur. En gros, le principe c'est: tu as une std::list dont les maillons sont stockés dans un std::vector<char>. Tu vas avoir des concessions sur la contiguïté au niveau du conteneur mais avec le pari que les maillons de la liste seront proches les uns des autres en mémoire, donc tu réduis quand même le risque de faute de page.
Une autre idée, est de travailler avec des pool de buffer que tu recycles, là c'est un peu plus compliqué à régler, parce qu'il faut avoir une idée assez précise du nombre de buffer dont tu as besoin, si tu en as trop, tu bouffes de la mémoire pour rien (et tu risques aussi la faute de page), si tu n'en as pas assez, tu risques un "bad_alloc" ou un engorgement.
Après, il faut aussi se souvenir que "Premature optimization is the root of evil", ton problème ressort typiquement de l'optimisation. Avant d'optimiser, il faut avoir une idée précise des point noirs, sinon tu vas passer des mois à optimiser un truc qui au final n'aura qu'une incidence très faible (voir nulle ou négative sur les performances)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Eug
Eug
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Eug