Partage
  • Partager sur Facebook
  • Partager sur Twitter

Avis de conception

    12 avril 2019 à 19:44:07

    Bonjour/Bonsoir,

    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:

    move(Buffer src, Buffer dst)
    {
        //... move instructions
        erase(hole);
    }
    
    erase(Hole hole)
    {
        //... erase instructions
        fillHole(hole,...);
    }
    
    fillHole(Hole hole,...)
    {
        //....
        move(..., hole);
    }

    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é...

    Merci d'avance.

    • Partager sur Facebook
    • Partager sur Twitter

    Eug

      12 avril 2019 à 20:04:13

      Pourquoi une "sémantique" à la std::vector et pas à la std::list ?

      Cela permettrait plus de flexibilité dont le fait d'avoir des trous invisibles pour l'utilisateur (slot invalidé).

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        12 avril 2019 à 20:55:09

        Etant donnée qu'il s'agit d'un projet de rendu 3D, j'evite au maximum tout ce qui n'est pas contigue en mémoire.
        • Partager sur Facebook
        • Partager sur Twitter

        Eug

          12 avril 2019 à 23:12:22

          Salut !

          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.

          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            12 avril 2019 à 23:44:16

            Lu',

            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.

            -
            Edité par eugchriss 12 avril 2019 à 23:47:38

            • Partager sur Facebook
            • Partager sur Twitter

            Eug

              13 avril 2019 à 4:34:23

              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)

              • Partager sur Facebook
              • Partager sur Twitter
              Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug

              Avis de conception

              × 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.
              • Editeur
              • Markdown