Manipulation d'expression par templates : la vengeance - C++ - Programmation
Marsh Posté le 04-09-2003 à 11:53:58
Je pense pas que tu puisse le faire dans un cadre général, tu va pouvoir optimiser ça pour des opérateurs particuliers ou des suites d'opérateurs particulières (du style a+b*c a+b+c ...)
Marsh Posté le 04-09-2003 à 12:05:12
c'est peut etre con, mais moi j'aurais fait
(x+y)/(u*v) renvoie une Expression+/*. cette expression contient des références
après tu as
uneFonction(Expression+/* e) // contructeur, conversion, membre
{
if(&e.x == &e.u and &e.y==&e.v)
{
version spécialisée
}
else
{
version générique
}
}
après je pense pas que tu puisse avoir quelque chose au moment de la compilation
Marsh Posté le 04-09-2003 à 13:19:04
ok ... bonc je vais etre obligé de me taper xxx fonction spar cas particuliers.
c'est ce que je commencait a craindre ...
Marsh Posté le 04-09-2003 à 13:20:52
Joel F a écrit : ok ... bonc je vais etre obligé de me taper xxx fonction spar cas particuliers. |
Ben ouaip, après tu peux peut être te limiter aux cas les plus fréquants, c à toi de voir
Marsh Posté le 04-09-2003 à 13:30:07
la solution que j'ai actuellement pass pr des variables muettes :
Code :
|
ca marche mais c moche
donc retour a la case parser/lexer avant compilation ...
Marsh Posté le 04-09-2003 à 13:38:21
et un truc du genre
(la syntaxe c peut être pas ça, ça fait 3 mois que j'ai pas touché un template, j'ai des absences )
Code :
|
Tu spécialise f de façon a pas charger 2 fois la même var en mémoire. Ca pourrait pas marcher? J'ai rien pour tester ici et je sais même pas si ça peut s'adapter à ton cas d'ailleur
Marsh Posté le 04-09-2003 à 13:48:22
Une piste. Y a des techniques assez intéressantes à découvrir dans la doc de Spirit. Par exemple sur l'utilisation de foncteurs conjugués avec le parsing: http://www.boost.org/libs/spirit/doc/functional.html
Marsh Posté le 04-09-2003 à 13:49:31
ACut a écrit : Une piste. Y a des techniques assez intéressantes à découvrir dans la doc de Spirit. Par exemple sur l'utilisation de foncteurs conjugués avec le parsing: http://www.boost.org/libs/spirit/doc/functional.html |
je lui ai déjà conseillé y a longtemps, mais il s'entête
Marsh Posté le 04-09-2003 à 13:57:16
Joel F > sinon, si tu veux eviter les tests comme ça, tu peux tenter des bidouiller des wrappers pour référence, tu te fais une fonction qui fait fusionner les alias que tu appelles à chaque fois qu'il faut. soit tu la fais binaire et tu l'appelles (n-1) fois (gaffe à l'implémentation) ou alors avec une liste template ( à coup de cons) (ou de boost::tuple)
Marsh Posté le 04-09-2003 à 14:00:01
Taz a écrit : Leto > |
Ca veut dire quoi ça, je me suis complétement planté ou c super génial? Non par ce que avec toi je me méfie, et vu que je suis absolument pas sûr de ce que j'ai écrit...
Marsh Posté le 04-09-2003 à 15:20:34
ReplyMarsh Posté le 04-09-2003 à 16:08:59
...soit il est mort.
C'est une hypothèse qu'on formule rarement mais il est déjà arrivé qu'elle se vérifie.
Marsh Posté le 04-09-2003 à 16:12:36
ACut a écrit : ...soit il est mort. |
Ouai mais là ça serait con il m'a pas encore mis sur son testament
Marsh Posté le 04-09-2003 à 16:27:21
Je suis pas mort, j'etais en reunion
@Leto : je crois aps qu ca marche &a c connu que a l'execution pas a la compilation.
@Taz : hmmm des precisions ?? la je comprends pas tout
Marsh Posté le 04-09-2003 à 16:29:22
Taz a écrit : je lui ai déjà conseillé y a longtemps, mais il s'entête |
je veux bien mais ou dois je mettre mon code altivec si je recod epas mes foncteurs a la main ??
Marsh Posté le 04-09-2003 à 16:30:09
sur ? moi je te dis juste, que le fastidieux, c'est de taper du code à chaque fois pour vérifier qui est qui. si tu wrappes tes références et que dans chaque fonction tu unique ( tuple <shared_ptr <Reference> > > ) ou un truc du genre, t'as moyen de trouver un traitement générique pour éliminer les alias.
Marsh Posté le 04-09-2003 à 16:33:02
Taz a écrit : sur ? moi je te dis juste, que le fastidieux, c'est de taper du code à chaque fois pour vérifier qui est qui. si tu wrappes tes références et que dans chaque fonction tu unique ( tuple <shared_ptr <Reference> > > ) ou un truc du genre, t'as moyen de trouver un traitement générique pour éliminer les alias. |
Justement sur ces wrappers de references ... en quoi ca va m'aider
Marsh Posté le 04-09-2003 à 16:40:34
ben comment tu veux faire ? tu peux pas affecter des références entre elles ?
Marsh Posté le 04-09-2003 à 16:41:06
Joel F a écrit : Je suis pas mort, j'etais en reunion |
Ben tu remplace par un opérateur == de ton cru
Marsh Posté le 04-09-2003 à 16:58:28
Taz a écrit : ben comment tu veux faire ? tu peux pas affecter des références entre elles ? |
y a un quiproquo la non
??
Marsh Posté le 04-09-2003 à 17:07:25
template<typename T>
class refWrapper
{
struct ref
{
T &r;
ref(T &i)
: r(i)
{}
private:
ref& operator=(const ref & );
ref(const ref & );
};
boost::shared_ptr<ref> rp;
public:
explicit refWrapper(T &r)
: rp( new ref(r) )
{}
refWrapper(const refWrapper &other)
: rp( other.rp )
{}
refWrapper& operator=(const refWrapper &other)
{
if(this != &other)
{
this->rp = other.rp;
}
return *this;
}
T& operator*()
{
return this->rp->r;
}
};
tu fais une daube comme ça
et apres, vu que tes références sont vers des objets de même type, tu dois avoir un moyen sympa de faire la chose
void f( truc &a, truc &b)
{
refWrapper aa(a);
refWrapper bb(b);
if(aa == bb) // tiens je l'ai pas ecris celui la
{
aa = bb;
}
call(*aa, *bb);
}
après tu peux faire un truc avec template, 1 par classe n-aire de fonction avec un tuple de refWrapper de longueur N, et tu bricoles les tests, comme ça à chaque fois
void fxwrapper( arg0, arg2, arg3, n-1)
{
tuple < ... > t(arg0, ..., argn-1)
unique(t);
fx(*t.get<0)>, ... t.get<n-1>());
}
mais peut etre je divague
mais peut etre je divague
Marsh Posté le 04-09-2003 à 17:15:36
je crois que je me suis complètement égaré dans mes pensées là. surtout sur la fin ...
Marsh Posté le 04-09-2003 à 17:19:22
Taz a écrit : je crois que je me suis complètement égaré dans mes pensées là. surtout sur la fin ... |
en fait j'en reviens au meme point qu'au début: soit des trucs anonymes, soit tu te cognes des spécialisation pour les cas favorables
edit: bon, j'ai fait nimp comme jamais, mais au moins j'ai réfléchi
Marsh Posté le 04-09-2003 à 17:29:21
bon merci quand même ...
ca fait 1 mois qu eje suis le nez dedans et je m'en sort ps ...
je crois que je vais reprendre le probleme calmement plu stard ..
j'ai autrement de quoi m'occupé d'ici la
Marsh Posté le 04-09-2003 à 17:30:42
de toutes façons, y aura du code à dupliquer en fonction de l'usage, le tout c'est de trouver la meilleur manière générique pour que l'appel soit élégant et que ça soit pas chiant à écrire
Marsh Posté le 04-09-2003 à 17:34:15
attends, le problème il est bien là
t1 = vec_ld(0,a.begin);
t2 = vec_ld(0,b.begin);
t3 = vec_ld(0,a.begin);
t4 = vec_ld(0,b.begin);
masi transformer en
t1 = vec_ld(0,a.begin);
t2 = vec_ld(0,b.begin);
t3 = t1
t4 = t2
ça serait bon?
Marsh Posté le 04-09-2003 à 18:04:32
spécialiser un template ca veut bien dire lui ajouter des membres qui ne fonctionnent que pour un type particulier ?
par exemple au lieu d'écrire
Code :
|
écrire
Code :
|
?
Marsh Posté le 04-09-2003 à 18:05:30
Presque :
Code :
|
écrire
Code :
|
est la bonne syntaxe
(et le rapport avec la choucroute )
Marsh Posté le 04-09-2003 à 18:07:23
bin dsl, je m'ecarte du sujet, taz a parlé de spécialisation, je comprenais pas, je demande ici plutot que d'ouvrir un nouveau topic
Marsh Posté le 04-09-2003 à 18:12:35
Code :
|
Marsh Posté le 04-09-2003 à 18:25:19
mis a jour . regarde l'affichage. l'idée est bete. tes différents paramtères peuvent en fait aliaser des variables communes. dans mon truc, un Vector est transformé en LVH une fois chargé avec load, le but étant de ne pas charger inutilement 2 fois le meme Vector. je refrabrique cette aliasing avec des UniqueLoader à base de shared_ptr qui partage un Vector, un lvh et un drapeau pour savoir si load a été appelé. ensuite j'ai mis tout ça dans mon tuple (je sais pas pourquoi, mais je pense qu'il doit y avoir un moyen de généraliser peut etre, et puis je peux appeler les constructeurs avec, mais bon, on pourrait faire avec des variables ou autres, j'y reviens), je farfouille mon tuple pour recréer les alias, c'est à dire, faire les affectations pour que les UL partagent les implémentations quand nécessaire.
ensuite, reste plus qu'a UL::load qui load s'il le faut et renvoie un LVH
l'affichage est concluant
pour les tuples, je pense que ya moyen de métaprogrammer tout ça, de manière d'exprimer l'opération d'alias sur un tuple de N éléments en fonctions de l'opération sur un tuple de N-1 éléments
Marsh Posté le 04-09-2003 à 19:04:38
Code :
|
Code :
|
ça marche (pas testé le 4, mais l'idée est là)
les UniqueLoader supporte parfaitement l'affecation, donc y a pas de problèmes si tout ce passe par copie, puisque les implémentations sont partagées. j'ai pas fait à coup de référence et de boost::tie, par ce que c'est plus long à écrire. attention avec boost::tuple, y a des surprises, voir la doc
on doit pouvoir faire par template pour avoir des jolis numéros <3>, mais gaffe encore à la manipulation des tuple, il faudra donc faire
template<typename Tuple, unsigned N> etc
Marsh Posté le 04-09-2003 à 19:43:38
nickel !!!
Evidemment moi, j'ai besoin de gerer tout les UniqueLoader pour 1 a N argument et remplacer les load par mes vec_ld !!!
Je teste tous ca et je te dit si ca marche
big merci
Marsh Posté le 04-09-2003 à 19:51:04
Bon :
CA MARCHE !
J'ai testé pour deux, trois et quatre arguments et le gain est de bien 35%. Je suis pas a 50% de plus bicose les tests et le fait que j'ai pas MPT les tuples mais c deja encourageant
MERCI !!!!
Marsh Posté le 04-09-2003 à 11:39:40
bon, mon générateur de code arithmétique optimisé Altivec par template marche.
Il me reste neanmoins un gros probleme.
Pour une expression du style :
R = (a+b)/(a*b);
mon générateur produit 2 chargements de la variable a et deux de la variable b :
au lieu de :
Moralité : 50% de perf en - que prevu.
Question :
En utilisant une technique d'expressions template ou dérivée, comment arrivez a ne generer qu'un chargement par occurence d'une variable dans les expressions ?
Plus geenralement comment 'flagé' des objets comme etant utilisé et ceci au moment de la compilation ?
Cf mes aures posts sur mes classes d'expressions pour les details. Je posterais un exemple minimaliste de code plus tard.
EIT : arf j'ai acheté un nouveau clavier
Message édité par Joel F le 04-09-2003 à 16:58:47