Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pourquoi vous faites des allocations dynamiques ?

24 août 2022 à 15:38:14

JadeSalina a écrit:

Ah cette fameuse phrase, quelqu'un l'a déjà sorti à Casey (c'était par rapport à imgui mais ça revient au même) https://guide.handmadehero.org/code/day493/#9114


Tu sais citer autre chose que Casey dans la vie ?
Et comme je te l'ai dit 1000 fois, je ne clique jamais sur les liens de Casey , c'est un argument d'autorité, je prend même pas le temps de le lire.
Et donc je te le redis y'a pas que le jeux video dans la vie !
Tu casse les bonbon à tout le monde pour des technique connu depuis 30 ans.
Tu donne des leçon sur des domaines que tu ne maîtrises pas.

Et non réduire l'allocation dynamique ne réduit pas forcement les perfs , ça réduira ta consommation de RAM dans des cas spécifique , y'a pas de méthode miracle.


JadeSalina a écrit:

Oui je sais qu'il y a des nuances, mais une solution moins performante même si elle plus rapide à faire reste moins bonne dans l'absolu, le mieux étant de passer plus de temps dessus pour avoir un truc mieux tout simplement


J'ai des doutes que tu connaisse ces nuances, vu que t'as fait 25 topic avec 100 réponses à répéter inlassablement la même chose , et le pire c'est que tu t'en lasse pas.
Et non c'est pas forcément plus "rapide" , mais tu as aucune notion d'optimisation du code,  ni d'architecture des CPU ou autre il me semble non ?
Lynix à montré un profiling , le bottleneck n'est pas dans l'allocation dynamique comme 95% des programmes ou JV , c'est fou hein ?

-
Edité par HelbaSama 24 août 2022 à 16:04:27

  • Partager sur Facebook
  • Partager sur Twitter
24 août 2022 à 22:13:45

HelbaSama a écrit:

Tu casse les bonbon à tout le monde pour des technique connu depuis 30 ans.

Tu donne des leçon sur des domaines que tu ne maîtrises pas.


Je suis d'accord avec ce message (et comme beaucoup d'autres postés par d'autres). Mais je pense que JadeSalina ainsi qu'OmbreNoire sont des personnes qui cherchent de l'attention (et souffrent peut-être d'un TDAH par la même occasion). Ainsi, tant que vous répondez, ils répondront.

Cette discussion ne fait que remonter tous les quatre matins, polluant ceux qui posent des questions plus importantes.

-
Edité par markand 24 août 2022 à 22:15:45

  • Partager sur Facebook
  • Partager sur Twitter

git is great because Linus did it, mercurial is better because he didn't.

24 août 2022 à 22:57:06

Je suis d'accord ,son comportement me faisais penser à OmbreNoir (et à d'autre personne que j'ai pu croiser sur des forums) , qui pose souvent les mêmes thème , qui troll , s'érige comme des personnes ayant la parole sainte (ou ici se fait le porte parole d'un autre).
Que il/elle ont tout compris mais que nous non etc etc.

Mais oui je suis d'accord le fond du problème a ce niveau est plus "personnel" tellement qu'il devient obsessionnel chez elle.

Mais je pense que les modo devrait plus faire quelque chose , je pense que c'est à eux de mettre le "holà" et de lui interdire de reposter ce genre de topic.
De toute façon ça doit être le 4 ou 5eme topic, je pense qu'il est complètement inutile encore de débattre dessus.

-
Edité par HelbaSama 24 août 2022 à 22:58:27

  • Partager sur Facebook
  • Partager sur Twitter
25 août 2022 à 10:33:35

Lynix a écrit:

JadeSalina a écrit:

Oui je sais qu'il y a des nuances, mais une solution moins performante même si elle plus rapide à faire reste moins bonne dans l'absolu, le mieux étant de passer plus de temps dessus pour avoir un truc mieux tout simplement

C'est totalement une pensée de débutant complet ça, un bon programme a bien d'autres qualités que simplement être le plus performant possible (quitte à gratter la moindre micro optimisation).

Finalement, on en revient à :

JadeSalina a écrit:

Si on achète une voiture d'occasion car on a pas d'argent, on va pas se dire que c'est une "bonne" voiture, non elle est nulle, il aurait été mieux d'acheter une lamborghini ou autre

A savoir, la stupidité de croire que parce qu'une solution est adapté à un endroit, elle l'est forcément partout. Et donc que pour partir en vacances, je devrais partir en lamborghini (ça va être pratique niveau coffre), les familles nombreuses devraient rouler en lamborghini (on va juste mettre les gamins sur le toit), les voyageurs de commerce devraient rouler en lamborghini (vivement leur radio du dos après quelques mois à faire ça). D'ailleurs, le moteur est vachement bien, je l'ai vu sur circuit. Du coup, on devrait faire des tracteurs qui utilisent le même moteur, et puis de camions aussi, et on devrait aussi mettre ça dans les propulseurs d'avions, et dans les bateaux aussi ...

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

25 août 2022 à 11:35:37

Comme toujours, les 2 roues sont laissées pour compte...
  • Partager sur Facebook
  • Partager sur Twitter
25 août 2022 à 17:28:21

Lynix a écrit:

D'après toi c'est plus simple d'écrire

if (dynamic_cast<CallFunctionExpression*>(node.get()) != nullptr)

que

if (node->GetType() == NodeType::CallFunctionExpression)

?

Non je trouve que c'est pourri le RTTI et qu'il faut pas s'en approcher (comme dit Casey, "I do not touch that with a 10 foot pole" https://guide.handmadehero.org/intro-to-c/day2qa/#1300)

Là où je veux dire que c'est plus "simple" c'est qu'il n'y aurait pas tout du à gérer les types manuellement, tout ce qu'il y aurait à faire à la limite c'est un petit helper du genre 

template<class T>
bool Is(const Node& node)
{
  return dynamic_cast<T*>(&node) != nullptr;
}

(que vous pourriez aussi rajouter d'ailleurs plutôt que de faire GetType())

Et on pourrait juste faire 

if (Is<CallFunctionExpression>(node))

Sans jamais devoir gérer à la main des enum Type et compagnie, mais comme je l'ai dit, je trouve aussi qu'il faut mieux se faire un RTTI maison, au prix de devoir gérer un peu plus de trucs à la main, c'est d'ailleurs ce que fait LLVM (https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html)

Lynix a écrit:

 et surtout qu'on peut facilement éviter.

Vous pensez ça du RTTI, et je pense pareil, mais moi j'étend cette pensée sur d'autres trucs, comme des allocations dynamiques, fonctions virtuelles etc (les allocs dynamiques je vais y venir juste après, et les fonctions virtuelles on peut faire du CRTP (Oh ! C'est ce que fait Clang :) https://clang.llvm.org/docs/RAVFrontendAction.html#using-the-recursiveastvisitor))

Après voilà je dit pas que ça va forcément poser un problème, mais disons que ça peut, alors qu'on peut facilement l'éviter c'est ça qui est dommage.

Lynix a écrit:

Fais-le donc dans mon code si tu veux, si tu as une idée qui sois plus performante sans contrepartie chiante, évidemment que ça m'intéresse.

Alors en fait je ne peux pas pouvoir mettre d'arena dans votre code, il faudrait à peu près tout changer, car oui la solution n'est pas d'ajouter un allocateur pool et de le mettre dans operator new, ça serait sans doute plus performant que mimalloc en temps d'exécution oui, mais c'est pas ça qu'il faut faire. Et les unique_ptr et autre, à chaque fois qu'on en a un dans le scope il va se faire détruire en sortie, même si on l'a move (ce qui est le cas le plus courant), et du coup on se paye un destructeur qui ne sert à rien du tout (juste un "if" pour savoir si il faut libérer le pointeur), peut être que le compilateur optimise mais rien n'est moins sûr...

gbdivers a écrit:

Je n’ai pas tres bien compris ce que tu proposes, Jade. Est-ce que tu peux reexpliquer depuis le debut la difference entre l’allocation dynamique et ce que Casey propose. En mettant les liens vers les videos de HandMadeHero. Merci.

Du coup j'y viens, on va prendre l'exemple du compilateur de Lynix. Au lieu de rendre les Node responsables de leurs fils avec des unique_ptr, l'idée serait qu'ils ne contiennent que des pointeurs nus, et que ces pointeurs soient alloués depuis une arena. On pourrait imaginer stocker pour chaque AST, l'arena contenant la mémoire correspondante (ou alors le stocker à côté, dans un ASTContext ou un truc comme ça). Du coup quand on veut créer un Node, on alloue linéairement depuis l'arena correspondant à l'AST et c'est tout. Pour la libération des ressources, au lieu que chaque Node détruise individuellement ses fils, ils serait tous détruits d'un coup lors de la libération de l'arena, qu'on libère au moment de détruire l'AST (qu'on peut mettre dans un destructeur pour pas avoir à le faire à la main). L'idéal étant bien sûr de ne pas avoir de destructeurs pour les trucs qu'on alloue, comme ça il n'y a juste rien à faire du tout, mais bon. Ça fait qu'on aurait en bonus tous les Node plus ou moins contigus en mémoire malgré la foire aux pointeurs qu'est un AST (ça on y peut rien c'est la structure elle même qui nous impose ça).

Et ça fonctionne très bien car quand on fait des allocations dynamiques gérées individuellement on prétend ne pas savoir ce qu'il y a à faire, alors que c'est faux, on sait très bien comment on construit l'AST, comment on l'utilise etc, on peut tout simplement allouer l'arena lors de la construction, la garder en mémoire tant qu'on manipule l'AST, et la libérer d'un coup quand on a fini. Et c'est ce genre de problème qui est en fait 90% des cas comme dit Casey, du coup l'arena est bien adaptée pour ça.

Je vous met quelques liens où il parle de ça :

"Use memory arenas to free memory depending on the scope (frame, level, etc.)" https://guide.handmadehero.org/code/day435/#10189

Un exemple de comment il gère le chargement de spritesheet et la décompression de PNG https://guide.handmadehero.org/code/day460/#103 

"memory arenas are good, once you get used to them, garbage collection becomes a non issue, 99% of the time, everything can happen in a temporary arena" https://guide.handmadehero.org/code/day462/#857 

"RAII is wrong, just use arenas, reference counting might be fine when we don't know the lifetime of things, but 99% of the time, we know it" https://guide.handmadehero.org/code/day468/#6310 

"I don't like garbage collection, I don't like new/delete" https://guide.handmadehero.org/code/day501/#7613 

Un exemple d'arena pour justement faire un parseur https://guide.handmadehero.org/code/day512/#3996 

Cet extrait est très rigolo, il montre des exemples de partitionnement mémoire, et il finit par le "WTF scheme" je vous laisse deviner lequel c'est :) https://guide.handmadehero.org/code/day085/#2062 

Après peut être que vous êtes plus habitués à faire du C++ moderne et donc que vous trouvez que c'est une prise de tête de faire comme ça mais Casey dans tout son jeu il fait comme ça et ça marche bien, et comme il dit on a pas vraiment besoin d'y penser, et surtout le gros avantage c'est que c'est plus performant que de toujours passer par un allocateur générique. Et il n'y a pas que Casey qui utilise ce genre de techniques, donc ne faites pas une attaque si vous tombez un jour sur un code qui fait ce genre de chose.

Et aussi c'est vrai que en C++ on a justement plein d'outils pour gérer sa mémoire facilement, c'est ce que montrait ce tweet https://twitter.com/cmuratori/status/1553951412878381057 mais le truc c'est qu'on peut s'en sortir très bien comme le fait Casey. Après quand il dit que ça marche dans 99% des cas, ça veut bien dire qu'il y a des cas où l'arena n'est pas adaptée, et ça je l'admet totalement, lui même il a fait un allocateur générique vers l'épisode 157 pour gérer la mémoire des assets dans la RAM (avant d'avoir le renderer GPU).

Et aussi c'est super pénible de débuguer avec des trucs de la STL on se retrouve dans plein de fonctions qui font rien, genre renvoyer la valeur de l'optional ou justement les destructeurs de unique_ptr qui font rien... Si vous savez comment dire à VS de ne pas step dans ces fonctions je veut bien

Ksass`Peuk a écrit:

A savoir, la stupidité de croire que parce qu'une solution est adapté à un endroit, elle l'est forcément partout. Et donc que pour partir en vacances, je devrais partir en lamborghini (ça va être pratique niveau coffre)

Dans le cas de ce dont je parle, il s'agit juste de faire mieux, donc oui mieux c'est mieux par définition. Si on fait semblant de pas savoir quoi/quand allouer de la mémoire et qu'on passe par un allocateur générique, ça sera moins bien que de minimiser le nombre d'allocations etc, car on sait ce dont on a besoin et quand. Après oui ça peut ne pas poser de problème car ça représente qu'une petite partie du temps total, mais ça reste moins bien. D'ailleurs Lynix comment se fait il que la lecture disque prenne tout le temps du compilateur ? Vous chargez bien tout le fichier d'un coup sans streaming n'est ce pas ? Et si vous prenez un énorme fichier peut être que les allocations vont commencer à se faire sentir

Après ne vous rendez pas malade pour tout ceci, je veux pas faire du mal autour de moi, je partage juste des trucs que je trouve cool et voilà, je vous dis pas de faire forcément comme ça ni rien. Et puis il y a des choses plus graves dans la vie, Lynix je suis vraiment désolée pour ce qui vous arrive en ce moment, ça va bientôt m'arriver aussi si vous voulez tout savoir. Je veux surtout pas critiquer ou dire du mal de ce que vous faites, les mini projets en live c'est ultra cool, et je l'avais déjà dit mais je trouve que vous êtes un des (le?) meilleurs streamers game dev FR, c'était la première fois que je voyais en france la philosophie comme Casey de "faire ses propres trucs à la main" etc. 

markand a écrit:

Cette discussion ne fait que remonter tous les quatre matins, polluant ceux qui posent des questions plus importantes.

Je ne sais pas si vous avez vu un de mes messages précédents je sais plus lequel, mais même si vous faites un petit peu "le dur" je sais que vous aussi vous êtes super cool

EDIT : flute encore un extrait qui m'était sorti de la tête, il est juste après celui sur le 10 foot pole, il dit que c'est très bien d'utiliser la STL si c'est efficace pour nous, et qu'il faut pas faire comme lui, qu'il faut faire ce que nous on trouve être le plus efficace et avec lequel on est le plus à l'aise, et qu'il pas écouter aveuglément ce que dise un tel ou un tel https://guide.handmadehero.org/intro-to-c/day2qa/#1410 

J'espère que vous allez pas avoir une mauvaise image de lui à cause de moi qui oublie certains passages

-
Edité par JadeSalina 25 août 2022 à 17:41:31

  • Partager sur Facebook
  • Partager sur Twitter
25 août 2022 à 18:19:40

Tu as cité 6-7 fois Casey sur un seul message ,chapeau l'artiste !
Et tu as mis 8 lien de handmade hero.

Si tu veux aller consulter, je pense que c'est le bon moment :)

Je n'argumenterais pas sinon on tournerai en rond , mais :

"Casey dans tout son jeu il fait comme ça et ça marche bien, et comme il dit on a pas vraiment besoin d'y penser, et surtout le gros avantage c'est que C'est plus performant que de toujours passer par un allocateur générique"

Si si ,tu es obligé d'y penser , mais comme t'as jamais fait de Jeu et encore moins un truc un peu ambitieux , je t'assure que t'es obligé d'y penser , et je parle d'expérience.


"Dans le cas de ce dont je parle, il s'agit juste de faire mieux, donc oui mieux c'est mieux par définition. Si on fait semblant de pas savoir quoi/quand allouer de la mémoire et qu'on passe par un allocateur générique, ça sera moins bien que de minimiser le nombre d'allocations etc, car on sait ce dont on a besoin et quand. Après oui ça peut ne pas poser de problème car ça représente qu'une petite partie du temps total, mais ça reste moins bien."


Oui alors une fusée , ça va super vite, c'est ce qu'il y'a de mieux, par contre en terme de maniabilité , c'est assez pourri.
Ce que tu fais, c'est ce que je t'avais dit , faire de la programmation statique , ça a des avantages et des inconvénients (et l'inconvénient c'est que t'es obligé de un d’être comme tu le dit dans un terrain connu , mais en plus ,c'est un peu hardcodé pas mal de chose ,enfin ici , ta gestion de ressource).

Et ce n'est pas mieux, parce que on soit , tu t'emmerde sur une machine relativement puissante (et je parle ici que même un Pentium 3 gérerai) , et que tu n’exploiterai pas ta machine, parce que a quoi bon gagner 2-4% ?

Par contre chez Casey , il n'a aucun intérêt de le faire, même pas pour l'opti qui représenterai absolument rien , il n'a pas de contrainte CPU ou de RAM , donc à part le faire pour le "fun".
D’ailleurs tu parle souvent de Casey et de l'opti , OpenGL , c'est pas optimisé a ce que je sache sur un GPU moderne.

Mais du coup ,tu demande ici a des gens qui connaissent cette technique , que certain utilise, de le faire sur tout leur projet pour le "fun".

-
Edité par HelbaSama 25 août 2022 à 18:26:45

  • Partager sur Facebook
  • Partager sur Twitter
25 août 2022 à 21:33:40

JadeSalina a écrit:

Et aussi c'est super pénible de débuguer avec des trucs de la STL on se retrouve dans plein de fonctions qui font rien, genre renvoyer la valeur de l'optional ou justement les destructeurs de unique_ptr qui font rien... Si vous savez comment dire à VS de ne pas step dans ces fonctions je veut bien

Sous VS c'est l'option "enable just my code"

  • Partager sur Facebook
  • Partager sur Twitter

En recherche d'emploi.

26 août 2022 à 1:39:57

> J'espère que vous allez pas avoir une mauvaise image de lui à cause de moi qui oublie certains passages

Il y a pas mal de gens qui ont une mauvaise image de lui sans le connaitre grâce à toi :p Car tu déformes pas mal ce qu'il dit et tu n'étais même pas au courant de pourquoi il codait de cette façon :/

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2022 à 12:12:28

Dalfab a écrit:

Sous VS c'est l'option "enable just my code"

Ah chouette merci !

ads00 a écrit:

Il y a pas mal de gens qui ont une mauvaise image de lui sans le connaitre grâce à toi :p Car tu déformes pas mal ce qu'il dit et tu n'étais même pas au courant de pourquoi il codait de cette façon :/

Ca c'est dommage il vaut mieux que vous alliez voir par vous même plutôt que de se baser sur ce que je dis 

HelbaSama a écrit:

Si si ,tu es obligé d'y penser , mais comme t'as jamais fait de Jeu et encore moins un truc un peu ambitieux , je t'assure que t'es obligé d'y penser , et je parle d'expérience.

Oui on doit probablement y penser dans certains cas je ne dis pas le contraire mais disons que on peut utiliser une arena dans plus de situations qu'il n'y parait, même si ça n'apporte pas forcément de gain significatif, mais on peut quand même l'utiliser, mais il y a forcément un gain puisque c'est plus rapide d'incrémenter un pointeur dans l'arena que de faire un malloc, que le gain soit perceptible ou non il est quand même là, même si c'est quelques microsecondes. Mais sinon oui il faut peut être réfléchir un peu plus que juste faire des make_unique, mais pas beaucoup plus, surtout quand on est dans le cas où on a un traitement à faire, on initialise, on fait le traitement, et on libère tout, et ce cas fonctionne très bien avec les arena, c'est ce qu'il utilise par exemple pour la décompression PNG, je sais pas si vous avez déjà codé un truc comme ça mais j'ai vu des gens se casser la tête sur la gestion mémoire de la décompression PNG alors qu'avec l'arena c'est tout simple.

HelbaSama a écrit:

D’ailleurs tu parle souvent de Casey et de l'opti , OpenGL , c'est pas optimisé a ce que je sache sur un GPU moderne.

Je sais pas ce qu'il utilise dans son vrai job, HH c'est juste un stream qu'il fait le soir, c'est pas un projet "sérieux", et il passe du temps à expliquer et réinventer la roue pour des raisons pédagogiques c'est pour ça que le jeu avance bien moins vite que ce qu'il devrait et quand il sortira starcodegalaxy ou 1935 qui vous dit que ça sera pas un truc incroyablement complexe, on verra bien car là pour le coup ce sont de vrais projets, il n'y aura pas l'excuse d'être en stream.

J'ai mis plein de liens de HH car c'est gbdivers qui a demandé, c'était peut être du troll mais dans le doute.

J'ai quand même envie de mettre l'arena dans le code de Lynix mais je sais pas quand je pourrais le faire, je ne suis pas trop dispo en ce moment. Et quand je dit qu'il faut "tout changer" ça ne veut absolument pas dire que le code actuel est mauvais, mais alors pas du tout, ce que ça veut dire c'est que cette technique demande de manipuler des allocateurs, ce qui n'est pas explicite dans le code actuel, donc il faut rajouter un paramètre "arena" pour les fonctions qui ont besoin de mémoire etc, on peut plus juste faire des make_unique dans le "vide" 

Et Lynix je ne sais pas comment vous avez fait le compilateur, où vous avez appris comment faire etc, mais si on regarde les compilateurs existants, ils allouent effectivement les Node depuis une pool, donc je pense que c'est juste "mieux", aussi minime que soit le gain je pense qu'il y en a un quand même. Après est ce qu'il vaut le temps supplémentaire passé, ça c'est pas sûr, on a peut être mieux à faire que de gagner quelques % je ne dis pas le contraire. (mais si on a du temps à perdre autant le faire non ?)

Mais sinon peut être que c'est pas si mal de faire des allocations dynamiques, je viens de retomber sur un extrait de Casey que j'avais pas le souvenir d'avoir vu, ça m'a un peu choquée je vous avoue https://guide.handmadehero.org/code/day271/#3670 ("dynamic memory allocation isn't bad" pour ceux qui cliquent pas sur les liens)

En fait je me suis peut être imaginé un monde parallèle en prenant que les morceaux qui m'intéresse mais en fait c'est même pas ce que Casey dit au final c'est moi qui voit le truc de travers (c'est à cause de vous que je retombe sur des passages que mon esprit avait inconsciemment ignoré, j'aurais préféré garder mon image de Casey que je me faisais !)

JadeSalina a écrit:

là on reconnait Casey pour avoir fait une API facile à utiliser et bien pensée :) (si vous avez pas la réf, il l'a dit lui même que là où il est le meilleur c'est dans le design d'API, mais à mon grand regret je peux pas vous passer le lien car je sais plus dans quel épisode il a dit ça)

Désolée de vous avoir laissé en plan tout ce temps sur cette réf, mais c'est bon j'ai retrouvé l'extrait en question !! https://guide.handmadehero.org/chat/chat001/#2020 

-
Edité par JadeSalina 26 août 2022 à 12:14:31

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2022 à 13:07:32

Tout gain de performance n'est pas bon à prendre.

Une modification du code pour engendrer un gain de performance, ça ne se fait pas juste parce qu'un gain est possible, ça se fait en comparant :

- Le gain (% de performances qu'on pourrait gagner)

- Le coût de cette modification (temps passé sur la fonctionnalité, complexité rajoutée au projet, dépendances rajoutées, rigidification de l'architecture engendrée, bugs potentiels rajoutés, etc.)

On obtient donc une balance gain / coût pour chaque optimisation propre à un projet, si cette balance est en défaveur de l'optimisation, alors celle-ci peut ne pas être intéressante.

La raison pour laquelle on n'utilise pas de memory arena, de pool à chaque instant pour chaque allocation n'est pas parce qu'on ne connait pas la technique ou qu'on ne sait pas comment la mettre en place, mais parce qu'on juge qu'elle n'apporte pas suffisamment par rapport à la complexité qu'elle rajoute.

Du coup on profile, on mesure.

Alors voici un petit test que j'ai fait, et si ça ne suffit pas à te convaincre vraiment je ne sais pas quoi faire de plus:

#define JADESALINAGE 0
#if JADESALINAGE

static std::uint8_t* memoryPtr = nullptr;
static std::size_t remainingSpace;

void* Allocate(std::size_t size, std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__)
{
	if (!memoryPtr)
	{
		fmt::print("JadeSalinenabled\n");
		remainingSpace = static_cast<std::size_t>(8) * 1024 * 1024 * 1024;
		memoryPtr = static_cast<std::uint8_t*>(malloc(remainingSpace));
	}

	void* ptr = memoryPtr;
	if (!std::align(align, size, ptr, remainingSpace))
		std::abort();

	memoryPtr = static_cast<std::uint8_t*>(ptr) + size;
	remainingSpace -= size;

	return ptr;
}

void* operator new(std::size_t n) noexcept(false) { return Allocate(n); }
void* operator new[](std::size_t n) noexcept(false) { return Allocate(n); }

void* operator new  (std::size_t n, const std::nothrow_t&) noexcept { return Allocate(n); }
void* operator new[](std::size_t n, const std::nothrow_t&) noexcept { return Allocate(n); }

void* operator new  (std::size_t n, std::align_val_t al) noexcept(false) { return Allocate(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return Allocate(n, static_cast<size_t>(al)); }
void* operator new  (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return Allocate(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return Allocate(n, static_cast<size_t>(al)); }

void operator delete  (void*, const std::nothrow_t&) noexcept {}
void operator delete[](void*, const std::nothrow_t&) noexcept {}
void operator delete  (void*, std::size_t) noexcept {}
void operator delete[](void*, std::size_t) noexcept {}
void operator delete  (void*, std::align_val_t) noexcept {}
void operator delete[](void*, std::align_val_t) noexcept {}
void operator delete  (void*, std::size_t, std::align_val_t) noexcept {}
void operator delete[](void*, std::size_t, std::align_val_t) noexcept {}
void operator delete  (void*, std::align_val_t, const std::nothrow_t&) noexcept {}
void operator delete[](void*, std::align_val_t, const std::nothrow_t&) noexcept {}

#endif

J'alloue 8GB de RAM et chaque allocation se voit être juste une incrémentation d'un pointeur, difficile de faire plus rapide.

Et j'ai benchmark 2000 compilations d'un shader représentatif de mon moteur (PBR) (et pour répondre à ta question plus haut, oui le fichier est lu en un seul appel à la fonction système sous-jacente).

Avant (allocations de base):

lynix@SirDesktop:/mnt/c/Projets/Perso/NazaraNext/ShaderLang$ xmake.exe
[ 90%]: compiling.releasedbg src\ShaderCompiler\main.cpp
[ 96%]: linking.releasedbg nzslc.exe
[100%]: build ok!
lynix@SirDesktop:/mnt/c/Projets/Perso/NazaraNext/ShaderLang$ time xmake.exe run nzslc --benchmark-iteration=2000 --measure --module "C:\Projets\Perso\NazaraNext\NazaraEngine\src\Nazara\Graphics\Resources\Shaders\Modules" ../../PhysicallyBasedMaterial.nzsl
- Full processing: 1594us
  - Read input file: 276us (global: 17%)
    - File reading: 30us (global: 1% - local: 11%)
    - Parse input: 218us (global: 13% - local: 79%)
  - Processing: 1016us (global: 63%)
    - Register module directory C:/Projets/Perso/NazaraNext/NazaraEngine/src/Nazara/Graphics/Resources/Shaders/Modules: 769us (global: 48% - local: 75%)
    - AST processing: 161us (global: 10% - local: 15%)

real    0m8.359s
user    0m0.002s
sys     0m0.000s

Et après, donc sans la moindre allocation dynamique (à part les 8GB au début)

lynix@SirDesktop:/mnt/c/Projets/Perso/NazaraNext/ShaderLang$ xmake.exe
[ 90%]: compiling.releasedbg src\ShaderCompiler\main.cpp
[ 96%]: linking.releasedbg nzslc.exe
[100%]: build ok!
lynix@SirDesktop:/mnt/c/Projets/Perso/NazaraNext/ShaderLang$ time xmake.exe run nzslc --benchmark-iteration=2000 --measure --module "C:\Projets\Perso\NazaraNext\NazaraEngine\src\Nazara\Graphics\Resources\Shaders\Modules" ../../PhysicallyBasedMaterial.nzsl
JadeSalinenabled
- Full processing: 1526us
  - Read input file: 342us (global: 22%)
    - File reading: 33us (global: 2% - local: 9%)
    - Parse input: 291us (global: 19% - local: 84%)
  - Processing: 974us (global: 63%)
    - Register module directory C:/Projets/Perso/NazaraNext/NazaraEngine/src/Nazara/Graphics/Resources/Shaders/Modules: 785us (global: 51% - local: 80%)
    - AST processing: 118us (global: 7% - local: 12%)

real    0m8.767s
user    0m0.000s
sys     0m0.002s

Le temps de processing d'une itération a donc baissé de 70 microsecondes, si on ne se concentre que sur la partie traitement de l'AST on économise à peine 30 microsecondes.

En plus de ça le programme met plus de temps à se lancer car une grosse allocation dynamique prend beaucoup plus de temps à être traitée qu'une petite allocation dynamique par le système, hé oui (ce temps n'est pas mesuré dans le benchmark du compilateur car les premières allocations dynamiques sont lors du processing des paramètres de ligne de commande).

On a donc une vague idée du temps qu'on peut économiser avec un memory arena, et il serait d'à peu près 1% en excluant le temps de traitement du memory arena lui-même.

En bonus, voici le profiling avec les allocations dynamiques et sans les allocations dynamiques.

En conclusion, à ce stade actuel du projet la balance bénéfice / inconvénient d'un memory arena n'est pas du tout sa faveur.

Est-ce qu'on peut arrêter de se battre contre des moulins maintenant ?

Edit: petite précision, ici je n'avais même pas mimalloc, ce qui signifie que je confronte l'allocateur de mémoire de base qui est tout moisi.

-
Edité par Lynix 26 août 2022 à 13:29:27

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)

26 août 2022 à 13:32:30

JadeSalina a écrit:

mais il y a forcément un gain puisque c'est plus rapide d'incrémenter un pointeur dans l'arena que de faire un malloc, que le gain soit perceptible ou non il est quand même là, même si c'est quelques microsecondes.

C'est fou de ne pas considérer le confort d'utilisation comme une optimisation , parce que plus y'a un confort de programmation, plus on peut facilement optimiser.

Sinon le gain que tu parle est nul , dans un JV pas tout le temps , mais en grande majorité, tu vas pas faire d'alloc in game ou très peu. donc que tu fait des alloc pendant le chargement , ça n'y change pas grand chose...
Les temps de chargements sont pas du au allocation dynamique.
Donc au final tu vas te faire chier pour aucun coût en fps in game, youpi , t'as beaucoup d'idée dans le genre ?

JadeSalina a écrit:

je sais pas si vous avez déjà codé un truc comme ça mais j'ai vu des gens se casser la tête sur la gestion mémoire de la décompression PNG alors qu'avec l'arena c'est tout simple.


C'est pas comme si j'avais pas dit que je faisais un memory arena pour mes projets, mais je l'utilise pas tout le temps , parce que ben y'a aucun intérêt d'utiliser cette méthode tout le temps (déjà dit plus haut pourquoi).

Par exemple , je l'utilise pour gérer la VRAM sur PS2 (et sur d'autre console) , et effectivement, c'est juste un truc à incrémenter (tu vois tu m'apprend rien ) , tu peux voir mon implémentation ici :
https://github.com/Kannagi/LMP3D/blob/master/AURAE/AURAE/PS2/Graphics/PS2_Vram.c

Mais si je le fais, c'est parce que la contrainte est assez forte , la PS2 c'est 4Mio de VRAM , et comme y'a le Framebuffer et le Zbuffer , je me retrouve avec du coup 2,5 Mio de VRAM , c'est assez peu surtout que la PS2 n'a pas de vrai compression de texture (juste du 8bpp ou du 4bpp).

(Pour ceux qui comprenne pas, ça évite d'avoir une fragmentation de la VRAM , vu que chaque kio compte  et secundo , je sais combien on peut allouer plus facilement )

-
Edité par HelbaSama 26 août 2022 à 14:05:47

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2022 à 13:44:25

Je corrige / complète mon message précédent, je ne suis pas sûr que la mesure interne soit fiable / adaptée pour ce genre de mesure, du coup j'ai réitéré avec cette modification rapide:

			auto start = std::chrono::steady_clock::now();

			constexpr std::size_t iterCount = 5000;

			for (std::size_t i = 0; i < iterCount; ++i)
				compiler.Process();

			auto end = std::chrono::steady_clock::now();

			std::cout << "one compilation takes " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / iterCount << "us" << std::endl;

Plus classique mais plus sûre.

Là on obtient 1620 microsecondes avec l'allocateur de base, 1530 avec le jadesalinage (un gain d'environ 5%, ce que je m'attendais un peu plus à avoir vu que le profiling attribue 10% sur l'allocateur de base). Un gain que je considère toujours comme trop faible face aux efforts qu'il demande.

Par contre là où ça devient très drôle c'est quand activer mimalloc me fait tomber à 1340 microsecondes, probablement grâce à une bien meilleure utilisation du cache du CPU, que la méthode JS explose complètement (ben oui, un stack allocator n'a pas que des avantages non plus).

Bref, si les allocations dynamiques sont un problème, commencez par utiliser un allocateur custom type mimalloc/jemalloc et compagnie. Là je vous avoue que le gain n'est pas dégueulasse (pour un effort quasi-nul), donc ça devient très intéressant (surtout quand on le compare à des memory arena faits maisons tout pourris).

Edit: au cas où ce n'est pas assez flagrant, on est en train de parler d'un gain de 300 microsecondes même avec mimalloc, ce n'est pas quelque chose de perceptible, le coût des allocations dynamiques n'est pas aussi élevé que JadeSalina l'affirme (en tout cas dans ce projet).

-
Edité par Lynix 27 août 2022 à 12:42:32

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)

26 août 2022 à 19:12:18

Ce qui pourrait être intéressant, c'est de comparer les chiffres avec des fichiers beaucoup plus gros (ou au contraire beaucoup plus petits) que ceux que tu as utilisé pour faire les tests.

Qui sait, peut-être serait il possible de trouver un cas particulier dans lequel l'arena de jade serait (largement) plus intéressante que tes allocateur customs ? :D

  • Partager sur Facebook
  • Partager sur Twitter
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
26 août 2022 à 19:39:10

koala01 a écrit:

Qui sait, peut-être serait il possible de trouver un cas particulier dans lequel l'arena de jade serait (largement) plus intéressante que tes allocateur customs ? :D



Je suis surpris que tu prend cela au "sérieux" , sachant que les principaux calcul se font pas dans l'allocation ,si dans ces test l'allocation "normal" fait 5% au mieux, ça pourra faire "0%".
D'ailleurs son mimalloc qui bat un truc qui n'alloue "rien" , et plus significatif , cela montre que les optimisations de cache sont bien plus efficace (sans surprise pour moi cela dit).


Là on obtient 1620 microsecondes avec l'allocateur de base, 1530 avec le jadesalinage (un gain d'un peu moins de 10%, ce que je m'attendais un peu plus à avoir vu que le profiling attribue 10% sur l'allocateur de base)



Alors j'ai sûrement mal compris ton calcul parce que entre 1620 -> 1540 , ça fait 6%. (1640 - 1640x0.06 = 1541)
  • Partager sur Facebook
  • Partager sur Twitter
26 août 2022 à 20:05:50

Bien sur que je ne prend absolument pas cela au sérieux :D

Quand un processus se termine en moins d'une seconde et qu'il a pour but de préparer le terrain pour quelque chose qui sera utilisé plus tard, je me dis que, même si on arrivais à diviser encore ce temps par dix, je ne verrais quand même plus la différence  ;)

Pour information, le temps de réaction moyen lors d'un réflexe est de l'ordre de 200 à 250 ms (oui, je parle bien de milli secondes  )... alors je doute que, dans cette situation, le fait de gagner l'équivalent du millieme du temps qu'il me faut pour un réflexe changera quoi que ce soit ;)

Par contre, mon fin fond scientifique qui a horreur de laisser des questions sans réponse serait sans doute ravi de savoir, à titre d'information, ce qu'il en est réellement :D

En d'autres termes, je ne me serais sans doute jamais posé la question par moi même car j'aurais sans doute trouvé que cela ne valait pas la peine.  Par contre; maintenant que la question a été posée, elle en vient à me tarauder et je trouve presque frustrant de ne pas avoir la réponse :D

  • Partager sur Facebook
  • Partager sur Twitter
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
27 août 2022 à 1:03:27

koala01 a écrit:

Ce qui pourrait être intéressant, c'est de comparer les chiffres avec des fichiers beaucoup plus gros (ou au contraire beaucoup plus petits) que ceux que tu as utilisé pour faire les tests.

Pour la science j'ai testé avec un fichier bien plus petit (le fichier avec lequel je faisais mes tests était le plus gros que j'avais), on est sur 110 microsecondes avec l'allocateur de base, 100 avec le jade salinage (en baissant à 512MB le bloc mémoire) et 85 avec mimalloc, moyennes de plusieurs runs.


On est dans des proportions très similaires. Et mêmes conclusions

HelbaSama a écrit:

Alors j'ai sûrement mal compris ton calcul parce que entre 1620 -> 1540 , ça fait 6%. (1640 - 1640x0.06 = 1541)

Les chiffres c'est compliqué.

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)

27 août 2022 à 23:03:24

Lynix a écrit:

HelbaSama a écrit:

Alors j'ai sûrement mal compris ton calcul parce que entre 1620 -> 1540 , ça fait 6%. (1640 - 1640x0.06 = 1541)

Les chiffres c'est compliqué.

Aha ça me fait penser à une fameuse phrase de Casey, "Math is hard, let's go shopping" https://guide.handmadehero.org/code/day364/#3690 et https://guide.handmadehero.org/code/day544/#6929 

(et il y a aussi une variante "typing is hard" https://guide.handmadehero.org/code/day394/#3040)

Lynix a écrit:

Est-ce qu'on peut arrêter de se battre contre des moulins maintenant ?

Au final vous aviez raison depuis le début, on s'en fiche de chercher à optimiser le moindre truc qui se voit même pas au final, il vaut mieux se concentrer sur l'algo et faire des trucs plus évolués. C'est en regardant le code du compilateur de Lynix que ça m'a fait une sorte de choc, je me suis rendue compte que c'était extrêmement sophistiqué et que je suis totalement incapable de faire un truc pareil. En fait je me rend compte que c'est mieux de faire des trucs sophistiqués comme ça plutôt que d'essayer de gagner un pouième de microseconde sur un truc tout basique. Désolée de vous avoir fait perdre tout ce temps et saoulé pendant des mois, c'était vraiment un comportement de m****. Si les modos veulent supprimer tous mes topics inutiles ne vous gênez pas.

Après l'arena de Casey je ne sais pas exactement à quoi ça ressemblerait dans le code de Lynix, il faudrait y réfléchir plus longtemps mais ça ne serait quand même pas aussi simpliste que juste allouer à la suite sans jamais désallouer. Et là l'allocation ne prend pas beaucoup de temps total car il y a la lecture sur le disque etc, mais si le fichier faisait plusieurs gigas, peut être que les allocations prendraient + que 5% par rapport au temps total ? J'aimerais bien quand même mettre une arena comme ce que Casey aurait fait mais je ne sais pas si je saurai le faire, c'est compliqué tout ça, comme il dit il vaut mieux aller faire du shopping :)

  • Partager sur Facebook
  • Partager sur Twitter
27 août 2022 à 23:53:19

JadeSalina a écrit:

Et là l'allocation ne prend pas beaucoup de temps total car il y a la lecture sur le disque etc

La lecture depuis le disque prend le même temps dans les trois tests (de base - jadesalinage - mimalloc), la seule chose qui fait varier le temps c'est l'allocation. Je précise également que je faisais les tests plusieurs fois (une première fois pour mettre le fichier en cache, puis plusieurs fois pour mesurer et faire une moyenne des valeurs obtenues) et que le programme et ses entrées sont sur un SSD NVMe M.2, normalement pas trop sujet à de grosses fluctuations du temps d'I/O.

En cas de besoin je veux bien faire le test avec un fichier chargé depuis la mémoire, c'est juste un peu plus long à mettre en place pour moi.

JadeSalina a écrit:

mais si le fichier faisait plusieurs gigas, peut être que les allocations prendraient + que 5% par rapport au temps total ? J'aimerais bien quand même mettre une arena comme ce que Casey aurait fait mais je ne sais pas si je saurai le faire, c'est compliqué tout ça, comme il dit il vaut mieux aller faire du shopping :)

Il n'y a aucune raison de croire que le pourcentage du temps occupé par les allocations grimperait avec un fichier plus complexe (on passerait plus de temps à faire des allocations, mais on passerait également plus de temps à faire les autres opérations - rien ne permet de dire que les proportions changeraient).

JadeSalina a écrit:

Désolée de vous avoir fait perdre tout ce temps et saoulé pendant des mois, c'était vraiment un comportement de m****. Si les modos veulent supprimer tous mes topics inutiles ne vous gênez pas.

Franchement à ce stade, je n'espère que deux choses:

1) Pour toi, que tu as pris un peu de recul (de façon durable) par rapport à ce que fait Casey (et d'autres devs) et compris qu'il ne fallait pas généraliser, que la programmation était une affaire de compromis et de choix.

2) Pour nous, que ce topic soit vraiment le dernier du genre.

Si tel est le cas, félicitations, tu viens de faire le premier pas pour devenir un jour une excellente développeuse.

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)

28 août 2022 à 14:04:32

JadeSalina a écrit:

En fait je me rend compte que c'est mieux de faire des trucs sophistiqués comme ça plutôt que d'essayer de gagner un pouième de microseconde sur un truc tout basique. Désolée de vous avoir fait perdre tout ce temps et saoulé pendant des mois, c'était vraiment un comportement de m****.

Hourra, c'est un miracle ! (et je t'ai mis un +1 rien que pour ça ).
J’espère que tu comprendra pourquoi pendant des mois j'ai radoté sur la complexité, et que cette complexité ne peut être réduite, et donc forcément il faudra faire des choses sophistiqué pour résoudre des problèmes complexe.

Et que oui , faut mieux sacrifié des pouieme de seconde et pouvoir faire des choses assez pointu , que d'avoir des perf "max" pour faire des trucs basiques.

Mais ça si tu écoutais ceux qui avait de la bouteille , on aurait pas tourner en rond pendant des mois...


Par contre je dirais faudra un moment ou un autre prendre du recul sur Casey vraiment.
Je rappel que tu viens de citer Casey pour une citation.

-
Edité par HelbaSama 28 août 2022 à 14:29:22

  • Partager sur Facebook
  • Partager sur Twitter
13 décembre 2022 à 22:18:59

Coucou c'est re moi, je viens en paix ne paniquez pas !

Je suis d'accord que c'est nul de chercher à optimiser le moindre truc et passer 3 mois pour une broutille qui se voit même pas dans le temps total au lieu de rajouter des fonctionnalités mais il y a quand même une question qui reste en suspens. Vous dites que l'arena de Casey c'est nul et du coup je suppose que Lynix et Dragonjoker aussi je crois, vous avez fait les choses "bien" dans votre propre compilateur (c'est à dire faire que chaque noeud stocke ses fils dans des unique_ptr). Alors pourquoi je tombe sur ça dans le code de Clang ? https://github.com/llvm/llvm-project/blob/c8647738cd654d9ecfdc047e480d05a997d3127b/clang/include/clang/AST/ASTContext.h#L607

Ils utilisent un allocateur "tout pourri" pour stocker tous les noeuds de l'AST et les libérer d'un coup à la fin, ce qui est bien ce à quoi aurait ressemblé la solution de Casey avec l'arena. C'est vrai que ça a l'air intéressant pour plusieurs raisons : l'allocation est très rapide, on peut récupérer des noeuds et les réutiliser dans d'autres noeuds au lieu de devoir les copier à chaque fois (unique_ptr oblige), et on peut se débarrasser de tout l'AST en un claquement de doigt puisque toute la mémoire est allouée à cet endroit (donc pas besoin de reparcourir l'arbre pour appeler les destructeurs).

V8 font la même chose, ils allouent tous les noeuds dans une arena (ils appellent ça une zone) https://github.com/v8/v8/blob/c3568fdb8750a3f89a5990a83759291c6861571d/src/ast/ast.h#L34 

D'ailleurs eux ils sont marrants, ils ont des structures explicitement conçues pour être utilisées avec des zones, et du coup vu que la mémoire est gérée dans la zone, ils se permettent carrément de ne pas appeler les destructeurs ! https://github.com/v8/v8/blob/c3568fdb8750a3f89a5990a83759291c6861571d/src/zone/zone-list.h#L57

Mais pour ce genre d'objet, on s'en fiche des destructeurs, la seule chose à libérer quand on détruit un noeud c'est la mémoire (oui un noeud c'est pas un thread ou un fichier qui eux nécessiteraient effectivement une destruction plus complexe), et vu qu'elle est géré ailleurs c'est pas la peine de le faire pour chaque noeud.

Leur zone : https://github.com/v8/v8/blob/c3568fdb8750a3f89a5990a83759291c6861571d/src/zone/zone.h#L28

Du coup pourquoi vous dites que c'est si pourri que ça alors que Clang et V8 font comme ça ?

  • Partager sur Facebook
  • Partager sur Twitter
13 décembre 2022 à 22:52:30

Tiens! JadeSalina rides again ...
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

14 décembre 2022 à 0:32:16

« Il est difficile de répondre à cette question sans plus d'informations sur ce qui a été dit précédemment et sur les raisons pour lesquelles l'arena de Casey est considérée comme "nulle". Toutefois, il est important de noter que les choix de conception et d'implémentation d'un allocateur de type arena dépendent de nombreux facteurs, tels que les besoins spécifiques de l'application, les contraintes de performance et de mémoire, ainsi que les préférences personnelles des développeurs. Par conséquent, il est possible que l'arena de Casey ne soit pas adaptée à certaines situations, mais qu'elle puisse être utile dans d'autres cas. En fin de compte, il est important de choisir l'approche qui convient le mieux à chaque situation, en prenant en compte les différents facteurs en jeu. »

Signé, ChatGPT.

-
Edité par jo_link_noir 14 décembre 2022 à 0:43:26

  • Partager sur Facebook
  • Partager sur Twitter
14 décembre 2022 à 1:37:58

Alors premier truc:
Est-ce que tu as vu quand ce projet a été commencé ?
En plein milieu de l'année 2009 !! (source: Code frequency · v8/v8 (github.com))

Est-ce que ça a vraiment du sens de s'appuyer sur un projet qui a démarré il y a si longtemps ?
Les techniques / normes ont évoluées en cours de projet, et il a probablement fallu faire des compromis histoire de ne pas repartir de zéro à chaque fois que "quelque chose de bien" pointait le bout de son nez (hé oui, les budgets ne sont pas extensibles).

  • Partager sur Facebook
  • Partager sur Twitter
15 décembre 2022 à 1:24:08

Ahaha ChatGPT la bonne blague !! ça comprend rien ce truc on peut pas discuter avec, ça raconte du grand n'importe quoi et le pire c'est que ça donne l'impression de dire des trucs vrais alors que non, c'est un complotiste le truc !!

JadeSalina: "Dans un AST en C++ est-ce qu'il vaut mieux stocker les noeuds fils avec des unique_ptr ou avec des pointeurs nus alloués à partir d'une memory arena ?" ChatGPT: "Il est généralement préférable d'utiliser des std::unique_ptr pour stocker les noeuds fils dans un arbre syntaxique (AST) en C++. Les std::unique_ptr sont des pointeurs intelligents qui prennent en charge la gestion automatique de la mémoire, ce qui peut simplifier considérablement le code et réduire les risques d'erreurs de fuites mémoire ou de désallocations accidentelles. Il est possible d'utiliser une "memory arena" pour allouer des pointeurs nus, mais cela peut rendre le code plus difficile à comprendre et à maintenir, en particulier lorsqu'il s'agit de gérer correctement la libération de la mémoire. De plus, les std::unique_ptr offrent des fonctionnalités supplémentaires telles que la possibilité de définir des destructeurs personnalisés pour les objets pointés, ce qui peut être utile pour gérer des ressources externes telles que des fichiers ou des sockets. En résumé, l'utilisation de std::unique_ptr est généralement la meilleure option pour stocker les noeuds fils dans un AST en C++."

JadeSalina: "C'est moins performant" ChatGPT: "Bien que l'utilisation de std::unique_ptr puisse entraîner une légère perte de performance par rapport à l'utilisation de pointeurs nus, cette perte est généralement négligeable et peut facilement être compensée par une implémentation efficace de l'algorithme en utilisant des structures de données et des algorithmes adaptés. En outre, la simplicité et la facilité de maintenance que procure l'utilisation de std::unique_ptr peuvent souvent compenser cette légère perte de performance en réduisant les erreurs et en permettant une meilleure compréhension du code. En général, il est donc recommandé d'utiliser des std::unique_ptr pour stocker les noeuds fils dans un AST en C++, même si cela peut entraîner une légère perte de performance."

JadeSalina: "Mais c'est très facile de libérer la mémoire avec une arena, il suffit de la libérer à la fin quand on a plus besoin de stocker l'AST" ChatGPT: "Il est effectivement possible d'utiliser une "memory arena" pour allouer des pointeurs nus et de libérer l'ensemble de la mémoire en une seule fois à la fin de l'utilisation de l'AST. Cependant, cela peut rendre le code plus complexe et difficile à maintenir, en particulier lorsqu'il s'agit de gérer correctement la libération de la mémoire. Par exemple, si l'AST est modifié ou mis à jour de quelque manière que ce soit après avoir été initialement alloué à partir de l'arena, il peut être difficile de gérer correctement la libération de la mémoire des noeuds modifiés ou supprimés. En outre, l'utilisation de std::unique_ptr permet de gérer automatiquement la mémoire de chaque noeud individuellement, ce qui peut être utile pour gérer les cas où des noeuds sont ajoutés ou supprimés de l'AST après sa création initiale. Cela peut également rendre le code plus facile à comprendre et à maintenir, car il est plus clair et explicite quant à la gestion de la mémoire des noeuds. En résumé, bien que l'utilisation d'une memory arena puisse être une option pour stocker les noeuds fils dans un AST en C++, il est généralement préférable d'utiliser des std::unique_ptr pour bénéficier de la gestion automatique de la mémoire et de la simplicité du code."

JadeSalina: "Mais Clang et V8 et d'autres font comme ça, tu vas pas dire que c'est des idiots non plus ??" ChatGPT: "Je ne dirais pas que Clang, V8 ou tout autre utilisateur de memory arenas pour stocker les noeuds fils dans un AST sont des idiots. Les développeurs de ces outils sont certainement des professionnels expérimentés et ils ont certainement de bonnes raisons pour choisir d'utiliser des memory arenas plutôt que des std::unique_ptr pour gérer la mémoire des noeuds. Cependant, cela ne signifie pas que l'utilisation de memory arenas est nécessairement la meilleure option pour tous les cas d'utilisation ou pour tous les développeurs. Il est important de noter que les besoins en matière de performance, de maintenabilité et de flexibilité peuvent varier considérablement d'un projet à l'autre, et il est donc important de choisir la solution de stockage des noeuds fils qui convient le mieux à vos besoins spécifiques. Dans certains cas, l'utilisation d'une memory arena peut offrir des avantages en termes de performance ou de flexibilité qui justifient son utilisation, tandis que dans d'autres cas, l'utilisation de std::unique_ptr peut être plus adaptée en raison de sa simplicité et de sa facilité de maintenance. En fin de compte, la meilleure approche dépendra de vos besoins spécifiques et il est important de prendre en compte tous les facteurs pertinents avant de choisir une approche de stockage des noeuds fils dans un AST en C++."

JadeSalina: "Les arena c'est mieux" ChatGPT: "Comme je l'ai mentionné précédemment, l'utilisation d'une "memory arena" pour stocker les noeuds fils dans un arbre syntaxique (AST) en C++ peut offrir des avantages en termes de performance ou de flexibilité dans certains cas. Cependant, il est également important de prendre en compte les inconvénients potentiels de cette approche, tels que la complexité accrue du code et la difficulté de gérer correctement la libération de la mémoire. En général, l'utilisation de std::unique_ptr pour stocker les noeuds fils dans un AST en C++ est considérée comme une approche plus simple et plus facile à maintenir, car elle permet de gérer automatiquement la mémoire des noeuds individuels et de bénéficier de fonctionnalités supplémentaires telles que la possibilité de définir des destructeurs personnalisés. Cela peut être particulièrement utile lorsque l'AST est amené à être modifié ou mis à jour de quelque manière que ce soit après sa création initiale. En fin de compte, la meilleure approche dépendra de vos besoins spécifiques et il est important de prendre en compte tous les facteurs pertinents avant de choisir une approche de stockage des noeuds fils dans un AST en C++."

JadeSalina: "MAIS T'ES VRAIMENT MATRIXÉ toi!! On s'en fout des destructeurs il n'y a rien à détruire, les noeuds c'est des petits POD tout mignons !!" ChatGPT: "Je suis désolé si j'ai donné l'impression d'être une intelligence artificielle comme celles qui apparaissent dans le film Matrix. Je suis en réalité un grand modèle linguistique entraîné par OpenAI pour répondre aux questions des utilisateurs de manière informative et utile. En ce qui concerne les destructeurs, il est vrai que les noeuds d'un arbre syntaxique (AST) en C++ peuvent souvent être de simples objets de données sans état (POD), dans lesquels cas il n'y a rien à détruire lorsque les noeuds sont supprimés. Cependant, il est possible que certains noeuds d'un AST aient des ressources externes associées, telles que des fichiers ou des sockets, qui doivent être correctement libérées lorsque les noeuds sont détruits. Dans ce cas, l'utilisation de destructeurs personnalisés définis avec std::unique_ptr peut être utile pour gérer correctement la libération de ces ressources externes. En résumé, bien que l'utilisation de destructeurs personnalisés ne soit pas toujours nécessaire pour les noeuds d'un AST en C++, ils peuvent être utiles dans certains cas pour gérer correctement la libération de ressources externes associées aux noeuds. Cela peut contribuer à rendre le code plus facile à maintenir et à éviter les fuites de ressources."

  • Partager sur Facebook
  • Partager sur Twitter
15 décembre 2022 à 2:52:43

Dans la discussion précédente, l'un des 2 interlocuteurs montre aucun signe d'intelligence et échoue au test de Turing...

  • Partager sur Facebook
  • Partager sur Twitter
15 décembre 2022 à 10:53:36

En tout cas, c'est bien tu as trouvé un interlocuteur de ton niveau pour tes question existentielles, tu peux arrêter de nous saouler, maintenant.

-
Edité par dragonjoker 15 décembre 2022 à 10:56:47

  • Partager sur Facebook
  • Partager sur Twitter

Si vous ne trouvez plus rien, cherchez autre chose.

15 décembre 2022 à 11:29:46

dragonjoker a écrit:

En tout cas, c'est bien tu as trouvé un interlocuteur de ton niveau pour tes question existentielles, tu peux arrêter de nous saouler, maintenant.


Sois pas méchant comme ça, tu vois bien qu'on a enfin quelqu'un capable de mesure et qui comprend pourquoi une solution n'est pas forcément adaptée à toutes les problématiques.

Jade est donc la première développeuse surpassée par une IA.

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)

15 décembre 2022 à 16:35:25

moi franchement j'ai été subitement convaincu par l'argumentaire qui tue tout : les arena c'est mieux. Rien à redire.

Sans rire, même le robot le dit, les arena sont une option, tout comme les std::unique_ptr sont une option. Il ne t'est jamais venu à l'esprit que Casey avait fait un CHOIX ? (en plus, basé sur son opinion biaisée de la STL)

Nous choisissons d'utiliser les unique_ptr, car bien qu'à priori ils soient légèrement moins performants, ils sont plus sécurisants et facilitent la relecture et la maintenance du code, et la gestion de la mémoire ainsi que les potentielles erreurs qui peuvent en découler.

Ca fait des mois que presque tout le monde ici l'a rabâché presque mots pour mots...

  • Partager sur Facebook
  • Partager sur Twitter
15 décembre 2022 à 18:40:00

JadeSalina a écrit:

Ahaha ChatGPT la bonne blague !! ça comprend rien ce truc on peut pas discuter avec, ça raconte du grand n'importe quoi et le pire c'est que ça donne l'impression de dire des trucs vrais alors que non, c'est un complotiste le truc !

Je crois au contraire que ChatGPT a bien mieux compris le problème soulevé par ta question que toi...

Car tu pars d'une idée fixe selon laquelle ce que peut dire ou faire un gourou quelconque est forcément parole d'évangile, et tu prends, pour t'en convaincre, l'exemple clairement choisi de manière biaisée qui tend en faveur de cette idée fixe.

Alors que l'IA à laquelle tu t'adresse, et qui n'est en définitive que l'implémentation d'un algorithme qui nécessite des heures et des mois d’entraînement est capable de te présenter des arguments aussi bien en faveur de ta propre thèse que des argument en faveur de la thèse adverse tout en marquant une préférence pour cette dernière.

Or, il se fait que, dans le cadre professionnel, c'est justement cette dernière thèse qui sera privilégiée, ce qui rend donc "logique" le fait que ce soit cette dernière thèse qui soit mise en avant par l'IA.

Si cet avis -- qui ne fait que refléter l'avis général, sois en certaine -- n'est pas le même que le tien, peut-être devrais tu commencer à remettre ton avis en question, en fonction des arguments présentés ;)

-
Edité par koala01 15 décembre 2022 à 18:41:27

  • Partager sur Facebook
  • Partager sur Twitter
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait