Quel conteneur pour mon problème ? - C++ - Programmation
Marsh Posté le 31-03-2010 à 15:08:22
C'est très abstrait, mais p'têt un truc du genre une structure rassemblant les paramètres + résultat, et ensuite une map associant une instance de cette structure pour chaque numéro de case sur laquelle un calcul a été effectué ?
Marsh Posté le 31-03-2010 à 17:26:26
En gros t'as une image et tu fais des calculs sur chaque pixel dont tu veux conserver chaque résultat ?
Marsh Posté le 31-03-2010 à 17:49:41
ca dépend aussi de la manière dont tu voudras utiliser ces résultats associés à ces paramètres.
Si c'est pour faire des recherches d'une case donnée régulièrement ou si c'est pour faire toujours des parcours linéaires complets de ta structure, tu vas pas faire le même choix
Marsh Posté le 31-03-2010 à 19:59:36
Par la suite, je ferais un parcours régulier sur toute l'image. Concernant les résultats à stocker, j'aurais besoin de faire au moins un tri sur chaque vecteur de résultat. Avant que vous me disiez que je n'ai qu'à garder le premier de chaque vecteur, je précise que je cherche justement à éviter ça.
Marsh Posté le 31-03-2010 à 20:27:11
snafu8 a écrit : Par la suite, je ferais un parcours régulier sur toute l'image. Concernant les résultats à stocker, j'aurais besoin de faire au moins un tri sur chaque vecteur de résultat. Avant que vous me disiez que je n'ai qu'à garder le premier de chaque vecteur, je précise que je cherche justement à éviter ça. |
Perso vu qu'à priori il n'y a rien de sparse, que tailles sont identiques et que tu ne cherches pas à maintenir une structure triée, mais juste à trier à la fin, je ne vois pas pourquoi ne pas utiliser des vectors.
Code :
|
Et puis à la fin tu fais un std::sort(pixel.begin(), pixel.end()) pour chaque pixel.
Tu initialises avec les bonnes tailles, tu insères en temps constant au fil de tes calculs et tu tries à la fin chaque pixel en O(nlogn).
Marsh Posté le 31-03-2010 à 21:17:30
l'heritage public de vector me fait pleurer du sang.
un héritage privé me semble de meilleur aloi vu que les classes de la stl ne sont pas conçus pour etre hériter publiquement.
Sinon ouais
Marsh Posté le 01-04-2010 à 10:11:00
Joel F a écrit : l'heritage public de vector me fait pleurer du sang. |
Comme on m'a appris comme ça en cours, je veux bien que tu développes cette aversion pour l'héritage public des std containers.
C'est parce qu'ils ne présentent pas tous la même interface ? Ou bien il y a une raison plus profonde ?
Je suis toujours ouvert pour m'améliorer ;-)
Marsh Posté le 01-04-2010 à 10:52:34
Lan Wezel a écrit : |
ils n'ont pas de destructeur virtuel, ca fait le premier argument lourd en défaveur d'un héritage public
Marsh Posté le 01-04-2010 à 11:02:16
Ok, là je veux bien qu'on m'explique le lien entre destructeur virtuel et héritage public.
Marsh Posté le 01-04-2010 à 11:06:16
Vu que ton image a une taille fixe, pourquoi pas un simple array de struct qui contiennent les infos dont t'as besoin ?
Marsh Posté le 01-04-2010 à 11:07:56
Pourquoi pas, je suis pas sectaire, je cherche juste à savoir quelles sont mes options, et, vu ce que je fais, laquelle serait la plus adaptée et la plus performante.
Marsh Posté le 01-04-2010 à 11:59:46
snafu8 a écrit : Ok, là je veux bien qu'on m'explique le lien entre destructeur virtuel et héritage public. |
l'héritage public te permet de manipuler directement ton instance sous forme de vector, sauf que, si tu détruits ton instance en la considérant comme un vecteur, tu n'appelleras pas le destructeur de ta classe.
Code :
|
l'execution du prog :
s@s /cygdrive/c |
CQFD : le destructeur de A n'a pas été appelé
Marsh Posté le 01-04-2010 à 12:07:31
theshockwave a écrit : |
+1
Je n'avais pas pensé à ce problème car quand j'hérite d'un std container, je n'utilise pas de polymorphisme sur cet héritage...
Vous m'embêtez parce j'aime bien ne pas avoir à surcharger explicitement toutes les méthodes membres des containers. Fénéant power !
Marsh Posté le 01-04-2010 à 12:37:30
si t'aimes bien faire du caca, c'est ton choix
Marsh Posté le 01-04-2010 à 12:51:03
snafu8 a écrit : Pourquoi pas, je suis pas sectaire, je cherche juste à savoir quelles sont mes options, et, vu ce que je fais, laquelle serait la plus adaptée et la plus performante. |
Dans la mesure où la taille de ton image est fixe, que la taille des données à stocker est fixe et déterminée à l'avance, autant faire du tout fixe avec un array de structs, qui t'apportera haute performance niveau accès mémoire et la plus faible utilisation mémoire possible vu que tu stockes le strict minimum.
C'est tellement un cas simple et évident que je m'imagine pas utiliser autre chose, c'est carrément un exemple idéal de l'utilisation d'un array et de structs.
Marsh Posté le 01-04-2010 à 12:52:45
Je suis fénéant, mais je suis conscient quand je fais du caca .
Enfin pour le coup du destructeur non virtuel j'y avait pas pensé. lalalala
Marsh Posté le 01-04-2010 à 13:16:38
Joel F a écrit : si t'aimes bien faire du caca, c'est ton choix |
Ouais enfin c'est un peu .
Bon ceci dit ça peut arriver qu'un nigaud détruise l'instance via un ptr sur std::vector<> ou autre truc dangereux, mais bon c'est un nigaud.
Moi le caca, je le vois surtout dans la logique du std::vector<> par pixel
Surtout qu'à priori ce sera bien le même nombre de paramètres/résultat pour tous les pixels.
Marsh Posté le 01-04-2010 à 13:27:44
bah, sur un vector, je peux appeler directement std::sort(), ou std::partial_sort(), sur une struct, c'est plus chiant, il faut que je re-fasse un truc idoine.
Tant qu'on y est, on écrit fainéant, hein (à moins de l'être vraiment à fond )
Marsh Posté le 01-04-2010 à 13:32:06
Si c'est une image, pourquoi est-ce que t'aurais à appeler cette fonction ?
Marsh Posté le 01-04-2010 à 13:45:49
Lan Wezel a écrit : |
En cas d'héritage privé, tu n'as pas besoin de les surcharger. Tu peux juste publier l'interface qui te convient, et ca prend pas beaucoup de temps, en général
Marsh Posté le 01-04-2010 à 14:31:50
Citation : |
Oups
Citation : |
Le but est pas de l'appeler sur l'image mais sur chaque vector d'expérience si je ne m'abuse.
Marsh Posté le 01-04-2010 à 16:02:47
Kenelm a écrit : Dans la mesure où la taille de ton image est fixe, que la taille des données à stocker est fixe et déterminée à l'avance, autant faire du tout fixe avec un array de structs, qui t'apportera haute performance niveau accès mémoire et la plus faible utilisation mémoire possible vu que tu stockes le strict minimum. |
BLABLA, std::vector à genre 0.1% d'overhead sur [] versus du pointeur crados, stop le FUD là
Marsh Posté le 01-04-2010 à 16:04:05
bjone a écrit : |
Je préfére faire le casse burne que laissez passser ça pour en voir 34567890 partotu aprés.
J'ai mon image de à conserver moi monsieur.
bjone a écrit : |
Deja un boost::multi_array me parait mieux pour l'aspect 2D, donc un truc genre
boost::multi_array< boost::array<float,N> >
est peut etre pas mal
Marsh Posté le 01-04-2010 à 16:16:29
Citation : Kenelm a écrit :
|
Bah nan attends, je stockes 300 000+ octets, je peux pas me permettre de prendre 3 pointeurs en plus pour faire un std::vector
Citation : Deja un boost::multi_array me parait mieux pour l'aspect 2D, donc un truc genre |
Je vais regarder mais ca me ferais mal que tu gagnes et que tu me fasses faire du boost:: (mauvaise foi inside). Ou alors la prochaine fois que tu passes, tu m'installes boost comme ça j'aurais plus d'excuses...
Marsh Posté le 01-04-2010 à 16:26:04
ReplyMarsh Posté le 01-04-2010 à 16:27:39
ReplyMarsh Posté le 02-04-2010 à 10:29:56
Joel F a écrit : BLABLA, std::vector à genre 0.1% d'overhead sur [] versus du pointeur crados, stop le FUD là |
Ce genre de chose fait vite une différence sur des larges volumes de données. Et du pointeur crados... aucune différence, le seul truc avec std::vector c'est que c'est aussi crado mais tu le vois pas.
Marsh Posté le 02-04-2010 à 11:06:08
Kenelm a écrit : Ce genre de chose fait vite une différence sur des larges volumes de données. Et du pointeur crados... aucune différence, le seul truc avec std::vector c'est que c'est aussi crado mais tu le vois pas. |
don't feed the troll.
Sinon, t'as des benchs significatifs sur tes "larges volumes de données" (et là, je demande des benchs avec les checks sur les itérateurs et dimensions désactivés) ?
Marsh Posté le 02-04-2010 à 11:17:19
J'aurais plus fait un truc du genre :
Code :
|
Je préfère avoir N vecteurs de x*y éléments que x*y vecteurs de N éléments, surtout que tu va itérer sur les x*y élements d'un seul set de paramètre quand tu fais ton calcul (donc autant te balader dans un seul tableau linéairement et ne pas fatiguer le cache).
[edit]
J'avais pas vu l'histoire du tri sur le vecteur de résultats Ça casse un peu l'histoire du cache, quoique si N est pas trop grand et avec un truc genre merge sort mais avec chaque phase du merge qui tourne sur tout le tableau, ça peut super bien passer en fait...
Marsh Posté le 02-04-2010 à 13:08:41
theshockwave a écrit : Sinon, t'as des benchs significatifs sur tes "larges volumes de données" (et là, je demande des benchs avec les checks sur les itérateurs et dimensions désactivés) ? |
J'ai fait pas mal d'assembleur, et j'ai souvent rencontré ce genre de problème. Et il est tout à fait logique qu'une commande qui prend plus de cycles d'horloge, bien que l'augmentation soit insignifiante, engendre une différence de plus en plus notable avec l'augmentation des itérations. Je vois même pas pourquoi je me casse le cul à expliquer ça d'ailleurs, c'est un fait très largement connu. Tout dépend derrière de la puissance disponible, de ce que tu cherches à faire... mais il y a clairement une différence.
Quoi qu'il en soit, si tu penses que tu peux faire plus rapide qu'un accès direct à la mémoire... ben écoute j'attends tes benchs.
Marsh Posté le 02-04-2010 à 13:10:18
Kenelm a écrit : J'ai fait pas mal d'assembleur, et j'ai souvent rencontré ce genre de problème. Et il est tout à fait logique qu'une commande qui prend plus de cycles d'horloge, bien que l'augmentation soit insignifiante, engendre une différence de plus en plus notable avec l'augmentation des itérations. Je vois même pas pourquoi je me casse le cul à expliquer ça d'ailleurs, c'est un fait très largement connu. Tout dépend derrière de la puissance disponible, de ce que tu cherches à faire... mais il y a clairement une différence. |
Ben un accès préfetché à la mémoire
Marsh Posté le 02-04-2010 à 13:29:09
Kenelm a écrit : J'ai fait pas mal d'assembleur, et j'ai souvent rencontré ce genre de problème. Et il est tout à fait logique qu'une commande qui prend plus de cycles d'horloge, bien que l'augmentation soit insignifiante, engendre une différence de plus en plus notable avec l'augmentation des itérations. Je vois même pas pourquoi je me casse le cul à expliquer ça d'ailleurs, c'est un fait très largement connu. Tout dépend derrière de la puissance disponible, de ce que tu cherches à faire... mais il y a clairement une différence. |
Sauf que quand tes volumes de données deviennent grand, c'ets les c ache misses puis les tlb misses qui vont devenir préponderant devant le cycle et demi d'indirection d'adresse.
Et si t'en ai encore à te toucher la nouille à faire de l'assembleur, j'ai une mauvaise nouvelle pour toi, les compilos font mieux que toi depuis bientot 5 ans.
alors,on est en C++, donc on utilise vector, multi_array et conseour. Sinon, t'as la catégorie C à coté. Merci d'être passé.
Spoiler : vendredi toussa |
Marsh Posté le 02-04-2010 à 14:10:41
Joel F a écrit : Sauf que quand tes volumes de données deviennent grand, c'ets les c ache misses puis les tlb misses qui vont devenir préponderant devant le cycle et demi d'indirection d'adresse. |
Si c'est mal codé, forcément...
Joel F a écrit : Et si t'en ai encore à te toucher la nouille à faire de l'assembleur, j'ai une mauvaise nouvelle pour toi, les compilos font mieux que toi depuis bientot 5 ans. |
Un compilateur va plus vite, mais j'ai encore du mal à trouver un compilateur qui fasse mieux qu'un être humain. Coder des goulots d'engorgement à la main peut faire gagner des grosses perfs. On gagne toujours à concevoir ses propres solutions.
Joel F a écrit : alors,on est en C++, donc on utilise vector, multi_array et conseour. Sinon, t'as la catégorie C à coté. Merci d'être passé. |
Me semble que la question de base c'était "c'est quoi le mieux ?"
Et vu l'époque à laquelle on vit, j'ai de plus en plus de mal à comprendre le sectarisme C/C++.
Joel F a écrit :
|
Excuse rejetée
Marsh Posté le 02-04-2010 à 14:20:51
Euh, on est bien entrain de parler de operator[] sur un vector versus operator[] sur de la mémoire là ? Genre le truc ou le code du premier est exactement le même que le second ? Le truc ou il faut vraiment insister et désactiver les variables d'induction et l'inlining pour que ça fasse une différence une fois compilé ?
Marsh Posté le 02-04-2010 à 14:55:24
0x90 a écrit : Euh, on est bien entrain de parler de operator[] sur un vector versus operator[] sur de la mémoire là ? Genre le truc ou le code du premier est exactement le même que le second ? Le truc ou il faut vraiment insister et désactiver les variables d'induction et l'inlining pour que ça fasse une différence une fois compilé ? |
je plussoie, le code généré avec optimisation du compilo est identique, d'où mon insistance pour les benchs, je ne sais pas d'où sortiraient ces miraculeuses instructions supplémentaires
Marsh Posté le 02-04-2010 à 14:56:25
theshockwave a écrit : |
du vilain compilo c++ qui fait qu'a faire du code lent bien évidemment
Marsh Posté le 02-04-2010 à 14:57:33
Kenelm a écrit : Si c'est mal codé, forcément... |
5% des gens savent ce qu'ai une TLB et 1% un cache. A part qqs experts, tout le monde code mal selon toi ?
Kenelm a écrit : Un compilateur va plus vite, mais j'ai encore du mal à trouver un compilateur qui fasse mieux qu'un être humain. Coder des goulots d'engorgement à la main peut faire gagner des grosses perfs. On gagne toujours à concevoir ses propres solutions. |
je te parlais de micro optimisation à la ouanagéne.
Kenelm a écrit : Me semble que la question de base c'était "c'est quoi le mieux ?" |
Le C, c'ets 1492, le C++ c'ets 2011 c'est tout.
Marsh Posté le 02-04-2010 à 15:25:58
Joel F a écrit : 5% des gens savent ce qu'ai une TLB et 1% un cache. A part qqs experts, tout le monde code mal selon toi ? |
Si on peut faire mieux, c'est que c'est mal foutu, non ?
Joel F a écrit : je te parlais de micro optimisation à la ouanagéne. |
Ah bah oui je me doute bien, mais moi aussi je parle d'optimisation
J'ai autre chose à foutre que coder des applis complètes en assembleur
Joel F a écrit : Le C, c'ets 1492, le C++ c'ets 2011 c'est tout. |
Ça sera 1492 le jour où on sera pas obligé de passer par le C pour gagner en perfs
Marsh Posté le 31-03-2010 à 15:00:51
Salut à tous,
je touche chaque jour un peu plus mes lacunes, et je suis face à un problème de conception sur lequel je voudrais votre avis.
Je dispose d'un tableau 1D de la forme
qui représente une image.
Pour chacune de ces cases, je vais faire N calculs, les calculs ne différant que par un jeu de 2 paramètres et renvoyant un seul résultat, en faisant une boucle sur N, puis une boucle sur l'image.
J'ai besoin de garder, pour chaque case de mon tableau la liste des résultats, ainsi que, pour chaque résultat, le jeu de paramètre qui l'a engendré. Quel genre de boîte serait adapté à ce problème?