Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3258 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Manipulation d'expression par templates : la vengeance

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

Manipulation d'expression par templates : la vengeance

n°507169
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 11:39:40  profilanswer
 

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 :
 

Code :
  1. vector float t1,t2,t3,t4;
  2. t1 =  vec_ld(0,a.begin);
  3. t2 =  vec_ld(0,b.begin);
  4. t3 =  vec_ld(0,a.begin);
  5. t4 =  vec_ld(0,b.begin);
  6. //calcul
  7. vec_madd(  vec_add(t1,t2), vec_re(vec_madd(t3,t4,zero)),zero);


 
au lieu de :
 

Code :
  1. vector char t1,t2;
  2. t1 =  vec_ld(0,a.begin);
  3. t2 =  vec_ld(0,b.begin);
  4. //calcul
  5. vec_madd(  vec_add(t1,t2), vec_re(vec_madd(t1,t2,zero)),zero);


 
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
mood
Publicité
Posté le 04-09-2003 à 11:39:40  profilanswer
 

n°507201
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 11:53:58  profilanswer
 

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


---------------
Le Tyran
n°507215
Taz
bisounours-codeur
Posté le 04-09-2003 à 12:05:12  profilanswer
 

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

n°507272
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 13:19:04  profilanswer
 

ok ... bonc je vais etre obligé de me taper xxx fonction spar cas particuliers.
c'est ce que je commencait a craindre ...

n°507274
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 13:20:52  profilanswer
 

Joel F a écrit :

ok ... bonc je vais etre obligé de me taper xxx fonction spar cas particuliers.
c'est ce que je commencait a craindre ...  


 
Ben ouaip, après tu peux peut être te limiter aux cas les plus fréquants, c à toi de voir


---------------
Le Tyran
n°507291
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 13:30:07  profilanswer
 

la solution que j'ai actuellement pass pr des variables muettes :
 

Code :
  1. eve::var<1> x;
  2. eve::var<2> y;
  3. r = apply( (x+y)/(x*y),a,b);


 
ca marche mais c moche :/
donc retour a la case parser/lexer avant compilation ...

n°507306
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 13:38:21  profilanswer
 

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  [:ddr555] )

Code :
  1. template<boolean test> toto f(const titi &, const titi &,);
  2. template<const titi &a, const titi &b> toto g()
  3. {
  4.    return f<&a == &b>(a,b);
  5. }


 
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  [:ddr555]


---------------
Le Tyran
n°507315
ACut
Posté le 04-09-2003 à 13:48:22  profilanswer
 

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


---------------
NOUVEAU! Le guide de l'édition en version ebook : http://marcautret.free.fr/autret/150q-ebook/
n°507318
Taz
bisounours-codeur
Posté le 04-09-2003 à 13:49:31  profilanswer
 

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

n°507320
Taz
bisounours-codeur
Posté le 04-09-2003 à 13:52:45  profilanswer
 

Leto >  [:xp1700]

mood
Publicité
Posté le 04-09-2003 à 13:52:45  profilanswer
 

n°507325
Taz
bisounours-codeur
Posté le 04-09-2003 à 13:57:16  profilanswer
 

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)


Message édité par Taz le 04-09-2003 à 15:14:11
n°507329
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 14:00:01  profilanswer
 

Taz a écrit :

Leto >  [:xp1700]  


 
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... :whistle:


Message édité par LetoII le 04-09-2003 à 14:00:24

---------------
Le Tyran
n°507417
Taz
bisounours-codeur
Posté le 04-09-2003 à 15:11:12  profilanswer
 

Joel F ?

n°507428
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 15:20:34  profilanswer
 


 
Soit il bosse, soit il est rentré chez lui :D


---------------
Le Tyran
n°507474
ACut
Posté le 04-09-2003 à 16:08:59  profilanswer
 

...soit il est mort.
C'est une hypothèse qu'on formule rarement mais il est déjà arrivé qu'elle se vérifie.


---------------
NOUVEAU! Le guide de l'édition en version ebook : http://marcautret.free.fr/autret/150q-ebook/
n°507480
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 16:12:36  profilanswer
 

ACut a écrit :

...soit il est mort.
C'est une hypothèse qu'on formule rarement mais il est déjà arrivé qu'elle se vérifie.


 
Ouai mais là ça serait con il m'a pas encore mis sur son testament  :whistle:


---------------
Le Tyran
n°507501
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 16:27:21  profilanswer
 

Je suis pas mort, j'etais en reunion :p
 
@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

n°507506
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 16:29:22  profilanswer
 

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 ??

n°507509
Taz
bisounours-codeur
Posté le 04-09-2003 à 16:30:09  profilanswer
 

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.

n°507516
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 16:33:02  profilanswer
 

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

n°507536
Taz
bisounours-codeur
Posté le 04-09-2003 à 16:40:34  profilanswer
 

ben comment tu veux faire ? tu peux pas affecter des références entre elles ?

n°507539
LetoII
Le dormeur doit se réveiller
Posté le 04-09-2003 à 16:41:06  profilanswer
 

Joel F a écrit :

Je suis pas mort, j'etais en reunion :p
 
@Leto : je crois aps qu ca marche &a c connu que a l'execution pas a la compilation.
 


 
Ben tu remplace par un opérateur == de ton cru  :whistle:


---------------
Le Tyran
n°507570
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 16:58:28  profilanswer
 

Taz a écrit :

ben comment tu veux faire ? tu peux pas affecter des références entre elles ?


 
y a un quiproquo la non :D  [:taimp]  
??  :??:

n°507592
Taz
bisounours-codeur
Posté le 04-09-2003 à 17:07:25  profilanswer
 

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


Message édité par Taz le 04-09-2003 à 17:17:19
n°507609
Taz
bisounours-codeur
Posté le 04-09-2003 à 17:15:36  profilanswer
 

je crois que je me suis complètement égaré dans mes pensées là. surtout sur la fin ...

n°507616
Taz
bisounours-codeur
Posté le 04-09-2003 à 17:19:22  profilanswer
 

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


Message édité par Taz le 04-09-2003 à 17:20:35
n°507633
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 17:29:21  profilanswer
 

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

n°507637
Taz
bisounours-codeur
Posté le 04-09-2003 à 17:30:42  profilanswer
 

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

n°507643
Taz
bisounours-codeur
Posté le 04-09-2003 à 17:34:15  profilanswer
 

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?

n°507656
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 17:46:32  profilanswer
 

oui c les vec_ld qui coutent cher.

n°507691
blackgodde​ss
vive le troll !
Posté le 04-09-2003 à 18:04:32  profilanswer
 

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 :
  1. template<class T>
  2. montemplate<T>::membre(T var)
  3. {
  4. //
  5. }


 
écrire

Code :
  1. template<class T>
  2. montemplate<T>::membre(int var)
  3. {
  4. //
  5. }


 
?


Message édité par blackgoddess le 04-09-2003 à 18:05:29

---------------
-( BlackGoddess )-
n°507693
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 18:05:30  profilanswer
 

Presque :
 

Code :
  1. template<class T>
  2. template::membre(T var)
  3. {
  4. //
  5. }


 
écrire

Code :
  1. template<>
  2. template::membre<int>(int var)
  3. {
  4. //
  5. }

 
 
est la bonne syntaxe
 
(et le rapport avec la choucroute  :??: )


Message édité par Joel F le 04-09-2003 à 18:06:03
n°507694
blackgodde​ss
vive le troll !
Posté le 04-09-2003 à 18:06:26  profilanswer
 

d'accord, merci :)


---------------
-( BlackGoddess )-
n°507695
blackgodde​ss
vive le troll !
Posté le 04-09-2003 à 18:07:23  profilanswer
 

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 :p


---------------
-( BlackGoddess )-
n°507701
Taz
bisounours-codeur
Posté le 04-09-2003 à 18:12:35  profilanswer
 

Code :
  1. #include <iostream>
  2. #include <boost/shared_ptr.hpp>
  3. #include <boost/tuple/tuple.hpp>
  4. struct Vector
  5. {};
  6. struct LoadedVectorHandle
  7. {
  8.   Vector *v;
  9.   LoadedVectorHandle(Vector *vv = 0)
  10.     : v(vv)
  11.   {}
  12. };
  13. LoadedVectorHandle load(Vector &v)
  14. {
  15.   return LoadedVectorHandle(&v);
  16. };
  17. class UniqueLoader
  18. {
  19.   struct Shared
  20.   {
  21.     Vector &v;
  22.     LoadedVectorHandle lvh;
  23.     bool loaded;
  24.     Shared(Vector &vv)
  25.       : v(vv), loaded(false)
  26.     {}
  27.   };
  28.   boost::shared_ptr< Shared> rep;
  29. public:
  30.   UniqueLoader(Vector &v)
  31.     : rep( new Shared(v) )
  32.   {}
  33.   UniqueLoader(const UniqueLoader &other)
  34.     : rep( other.rep )
  35.   {}
  36.   UniqueLoader& operator=(const UniqueLoader &other)
  37.   {
  38.     if(this != &other)
  39.       {
  40. this->rep = other.rep;
  41.       }
  42.     return *this;
  43.   }
  44.   LoadedVectorHandle load()
  45.   {
  46.     if(!this->rep->loaded)
  47.       {
  48. this->rep->lvh = ::load(this->rep->v);
  49. this->rep->loaded=true;
  50. std::cout << "loaded " << static_cast<void*>(&this->rep->v) << '\n';
  51.       }
  52.     return this->rep->lvh;
  53.   }
  54.   Vector* operator*()
  55.   {
  56.     return &this->rep->v;
  57.   }
  58. };
  59. void compute(LoadedVectorHandle a, LoadedVectorHandle b, LoadedVectorHandle c)
  60. {
  61.     std::cout << "compute "
  62.     << static_cast<void*>(a.v) << ' '
  63.     << static_cast<void*>(b.v) << ' '
  64.     << static_cast<void*>(c.v) << '\n';
  65. }
  66. void computeWrapper(Vector &a, Vector &b, Vector &c)
  67. {
  68.   std::cout << "computeWrapper "
  69.     << static_cast<void*>(&a) << ' '
  70.     << static_cast<void*>(&b) << ' '
  71.     << static_cast<void*>(&c) << '\n';
  72.   boost::tuple< UniqueLoader, UniqueLoader, UniqueLoader > args(a, b, c);
  73.   if( *args.get<0>() == *args.get<1>() )
  74.     {
  75.       args.get<0>() = args.get<1>();
  76.     }
  77.   if( *args.get<0>() == *args.get<2>() )
  78.     {
  79.       args.get<0>() = args.get<2>();
  80.     }
  81.   if( *args.get<1>() == *args.get<2>() )
  82.     {
  83.       args.get<1>() = args.get<2>();
  84.     }
  85.   compute( args.get<0>().load(), args.get<1>().load(), args.get<2>().load() );
  86.   std::cout << std::endl;
  87. }
  88. int main()
  89. {
  90.   Vector a, b, c;
  91.   computeWrapper(a, b, c);
  92.   computeWrapper(a, a, b);
  93.   computeWrapper(a, a, a);
  94. }


Message édité par Taz le 04-09-2003 à 18:32:53
n°507707
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 18:14:52  profilanswer
 

hmm je vois la chose ...
 
qss expiclations qd même :p

n°507719
Taz
bisounours-codeur
Posté le 04-09-2003 à 18:25:19  profilanswer
 

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

n°507763
Taz
bisounours-codeur
Posté le 04-09-2003 à 19:04:38  profilanswer
 

Code :
  1. static inline void Unique2(boost::tuple<UniqueLoader, UniqueLoader> t)
  2.   {
  3.     if( *t.get<0>() == *t.get<1>() )
  4.       {
  5. t.get<0>() = t.get<1>();
  6.       }
  7.   }
  8.   static inline void Unique3(boost::tuple<UniqueLoader, UniqueLoader, UniqueLoader> t)
  9.   {
  10.     Unique2( boost::make_tuple(t.get<0>(), t.get<1>()) );
  11.     Unique2( boost::make_tuple(t.get<0>(), t.get<2>()) );
  12.     Unique2( boost::make_tuple(t.get<1>(), t.get<2>()) );
  13.   }
  14.   static inline void Unique4(boost::tuple<UniqueLoader, UniqueLoader, UniqueLoader, UniqueLoader> t)
  15.   {
  16.     Unique3( boost::make_tuple(t.get<0>(), t.get<1>(), t.get<2>()) );
  17.     Unique3( boost::make_tuple(t.get<0>(), t.get<1>(), t.get<3>()) );
  18.     Unique3( boost::make_tuple(t.get<0>(), t.get<2>(), t.get<3>()) );
  19.     Unique3( boost::make_tuple(t.get<1>(), t.get<2>(), t.get<3>()) );
  20.   }


 

Code :
  1. boost::tuple< UniqueLoader, UniqueLoader, UniqueLoader > args(a, b, c);
  2.   UniqueLoader::Unique3(args);


 
ç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


Message édité par Taz le 04-09-2003 à 19:07:28
n°507797
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 19:43:38  profilanswer
 

[:taimp] 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 :p
 
 :jap: big merci

n°507801
Joel F
Real men use unique_ptr
Posté le 04-09-2003 à 19:51:04  profilanswer
 

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 :D
 
MERCI !!!!

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Manipulation d'expression par templates : la vengeance

 

Sujets relatifs
[CSS] height d'un div reglé par expression[C] Question sur les union et gestion de priorités dans une expression
expression reguliere[JS] Regular expression
templates de formulaires pour PHPManipulation de string c++
[Meta-prog] Les templates-ExpressionsSpécialisation des templates
PHP expression reguliere helpExpression Reguliere ... Où est le problème ?
Plus de sujets relatifs à : Manipulation d'expression par templates : la vengeance


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)