FONCTIONS USUELLES (TRIGO) EN METAPROGRAMMATION

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 7 juin 2007 à 15:50
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 - 20 juin 2007 à 19:57
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/43027-fonctions-usuelles-trigo-en-metaprogrammation

coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
20 juin 2007 à 19:57
je te laisses le loisir de refaire le bench si tu doutes, mon prof de math dit que cos utilise un dl, donc, si cos utilise un dl18 et que j'ai besoin de la precision d'un dl5, evidement...
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
10 juin 2007 à 15:56
Le DL plus rapide au runtime que le cos ? oah, je savais pas.
Mais, de toute façon, au pire tu fais une lookup table de disons 360 valeurs ;) imbattable pour la vitesse ( comment ça pour la précision c'est lamentable ? ^^ )

Pour ton bench : le calcul prend suffisement de temps ? parce que bon, clock() ...
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
10 juin 2007 à 11:16
math.h te renvoi souvent trop de decimales pour cos et sin... tu t'en fous generalement que ton float ai une valeur legerement erronee car finalement, quand tu convertis en int a la fin pour placer ton point a l'ecran, bah tu perds cette precision, et meme si t'avais un decalage, decaler d'un pixel ou deux, c'est pas forcement genant...

Calculer un DL8, ca donne Math<float, 4>::cos(...) de cosX, et la, X peut etre variable, et on a une meilleur vitesse que cos dans <math.h>

18446744073709441616 - 1
18446744073708791616 - 1


pour float a;
clock_t begin, end;
float b=3;
begin = clock();
for (int i=1;i<900000;i++){
a=cos(b/i);
}
end = clock();
std::cout << (unsigned long long)(begin - end) << " - " << a << std::endl;
begin = clock();
for (int i=1;i<900000;i++){
a=Math<float, 6>::cos(b/i);
}
end = clock();
std::cout << (unsigned long long)(begin - end) << " - " << a << std::endl;

(en compilant avec -O2 -O3 sous g++, on est plus rapide que math.h) et un DL8 sur des fonctions genre cos(x), c'est deja d'une bonne precision...
bon, et sans parler de ca, pour les constantes, c'est du bonheur :)
De plus, calculer sur toute classe qui overload les operations + / * et -, je trouve ca plutot utile personellement...
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
10 juin 2007 à 10:43
Mais il aime ça, je crois ;)
pour le "imitable" on est à 100% d'accord. cf ma remarque: "Faisable aussi en asm, on est bien d'accord ! Mais automatisé en C++."

Par contre, dans le cadre de cette source bien précise, j'en viens à me poser la question de l'utilité: ça t'arrives souvent d'avoir à calculer des développements limités , connus à la compil qui plus est ? moi pas ^^
Remarque que je ne porte aucune critique sur ton code, hein, c'était juste une remarque.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
10 juin 2007 à 08:01
juste dans le but de virer les templates ? tu lacerais mapple ou autre ? pour avoir un dl50...

apres t'aurais un code incomprehensible (enfin ca, on a l'habitude...), et impossible a modifier
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
10 juin 2007 à 06:07
avec les valeurs non constantes, ca depend comment t'as bosse... exemple : je ne alcule pas de factorielle sur une var non constante, mais je peux calculer un cos sur un truc non constant
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
10 juin 2007 à 01:34
"version template bat l'asm" n'a pas de sens, le compilo produit un asm... donc au moins imitable.
Le 'metaprogrammé' donne les mêmes résultats précalculés avec des valeurs non connues à la compil ?
Bien des lustres que je n'ai pas abordé ce sujet, faudrait voir.
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
10 juin 2007 à 01:26
ça va assez vite virer au troll C vs C++ jle sens ...
BruNews, fan de benchmarks que tu es, que dirais tu d'un chti essai entre un code comme ça:
Vect3D res = V1 + 4*V3;
en C ( voire en asm ) et en C++ métaprogrammé?

Théoriquement la version template bat l'asm, aussi fou que cela puisse paraître, car le compilo n'a pas a faire un arbre de calcul genre temp1 = V3, temp1.operator*(4) , temp1.operator+(V1), trucs du genre
Faisable aussi en asm, on est bien d'accord ! Mais automatisé en C++. Boost le fait assez bien je crois.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 juin 2007 à 23:15
Bien d'accord coucou, faisons bosser les machines.
Mon idée est juste de mettre ce code dans un outil qui donne la constante à insérer dans le code, ça évite de se trimballer ces templates partout.
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
9 juin 2007 à 23:06
Ben, je peux pas dire que je suis fan des define, mais la un truc genre
#define factoriellei(a) Math::factorielle(); ne me déplairaît pas trop, qu'en pensez-vous ?
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
9 juin 2007 à 16:55
personellement, je ne suis pas assez maso pour ecrire moi meme un DL50 de cos(x) en 0... on a des machines pour ca... autant faire une lib qui nous epargne ce travail (chose faite ici)
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 juin 2007 à 12:39
arnaud16022 >
Non je n'emploie jamais cette prog. Technique certes connue mais comme d'hab je lis description et code en (moins que) diagonale, journées beaucoup trop courtes.
Quand je ne veux pas d'appel de fonction, je mets la valeur en dur, ce que fait le compilo.
Faut bien reconnaitre que j'emploie peu l'optimisation du compilo... encore que là on ne peut pas vraiment appeler ça ainsi, c'est un précalcul que je fais moi même d'ordinaire.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
9 juin 2007 à 12:08
en debug, ca ne donne rien de bon a ce sujet sous vc apparement...

la syntaxe, tu reproches le class T ? tu prefererais un truc genre Math<50>::... directement ?
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
9 juin 2007 à 11:57
Effectivement c'est plus rapide au runtime, mais je trouve la syntaxe très laide... on est bien d'accord, c'est de la syntaxe classique de métaprogrammation, mais je serais personnellement assez pour des typedef pour les types les plus fréquents.

Brunews -> bah ça alors tu ne connaissais pas ? j'avoue ne jamais avoir codé de truc comme ça personellement, mais la technique est connue ... venant de toi c'est surprenant :)
Anyway, merci pour l'option de sortie asm, jusqu'à présent je devais compiler en debug et regarder le désassembly au runtime :/
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
9 juin 2007 à 01:55
sous g++ faut compiler avec l'option -O2 et on a les memes optimisations
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 juin 2007 à 09:42
mov eax, valeur
ret 0

Voila tout ce qu'il y a, les calculs sont faits à la compilation comme dit en description (et que j'avais zappé).
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
8 juin 2007 à 05:32
t'as les asm dans les fichiers html, ils correspondent aux mains commentes dans tcml.cpp
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 juin 2007 à 21:20
Sous VS hyper simple.
Proprietes du projet, onglet C/C++, fichier de sortie
et tu indiques "Assembler + code source".
Tu trouveras fichier asm dans dossier release.

Attention à ce genre de petite fonction, VC pourrait ne pas empiler de param etc...
Faut faire au moins 2 appels de chaque dans ton main avec params dofferents pour assurer la sortie du vrai code.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
7 juin 2007 à 21:07
... j'etais sous windows a l'instant pour voir ce que ca rendait :
Suite a quelques conseils de NitRic, j'ai pris cette fonction main
int main(){
int a;clock_t begin, end;begin = clock();
for (int i=0;i<9000000;i++){
a=1;
for (int j=1;j<=15;j++)
a*=j;
}
end = clock();
std::cout << (unsigned long long)(begin - end) << " - " << a << std::endl;
begin = clock();
for (int i=0;i<9000000;i++)
a=Math::factorielle();
end = clock();
std::cout << (unsigned long long)(begin - end) << " - " << a << std::endl;
return 0;
}

sous visual en release:
18446744073709551148 - 2004310016
0 - 2004310016

sous linux (g++), ou sous visual en debug, j'ai quelquechose de different :
18446744073708611616 - 2004310016
18446744073708691616 - 2004310016

il te faudrait l'asm fourni par quel compilateur ? (pardonne moi, je ne sais pas utiliser vs, je ne sais pas lui faire cracher un assembleur, ni meme a g++ d'ailleur, et le man page de g++ fait 8000 ligne :()
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 juin 2007 à 19:57
stp coucou, donne nous asm généré pour les 2 formes de factorielle par exemple avec le C/C++ correspondant.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
7 juin 2007 à 18:44
gcc ne fait pas tout ce qu'il pourrait faire a la compilation, je testerais sous vs ce soir... (mais ma factorielle reste inferieure en temps a une boucle)
spiky31 Messages postés 106 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 11 février 2008
7 juin 2007 à 16:56
Désolé mais la ca na rien avoir avec la recursion ...

Coucou747 l'a bien expliqué : les calculs sont effectués a la COMPILATION.

Cette technique porte d'ailleurs un nom : la meta-programmation.

Confére ici : http://loulou.developpez.com/tutoriels/cpp/metaprog/
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 juin 2007 à 15:50
récursion = risque explosion de la pile + lenteur.
Rejoignez-nous