Pages : 1
#1 Le 22/04/2008, à 17:41
- scholi
préprocesseur C
Bonjour à tous, j'ai un petit soucis. Je dois utiliser une macros dont une partie dépend d'une condition. Exemple
#if X==1
#define A std::cout << "X égal 1\n";
#else
#define A std::cout << "X ne vaut pas 1\n";
#endif
ce qui est un peu lourd et je me demandais si l'on ne pouvait pas simplifier du genre:
#define A std::cout << "X
#if X==1
#define A A##égal
#else
#define A A##ne vaut pas
#endif
#define A A## 1\n";
Bon là dans cette exemple c'est pas plus simple, mais ma macro est aussi un brin plus compliquée que std::cout
évidement mon deuxième code ne fonctionne pas et c'est là toute ma question. Comment pourrais-je faire ma macro de tel façon que ça marche?
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
Hors ligne
#2 Le 22/04/2008, à 18:12
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
Scholi, que penses-tu de ça :
#if X == 1
#define CHAINE "égal"
#else
#define CHAINE "ne vaut pas"
#endif
#define A std::cout << "X " << CHAINE << " 1\n"
Que je teste par exemple ainsi :
#include <iostream>
#define X 1
#if X == 1
#define CHAINE "égal"
#else
#define CHAINE "ne vaut pas"
#endif
#define A std::cout << "X " << CHAINE << " 1\n"
int main (void) {
A;
return 0;
}
Cela dit, vu que tu fais du C++ et dans la mesure où il existe les directives const et inline, tu ne devrais pas avoir recourt à #define pour autre chose que protéger tes en-têtes. Pour faire simple : #define en C++, c'est mal.
Par exemple :
#include <iostream>
#include <string>
namespace General {
const int X = 1;
const std::string CHAINE = (X == 1)? "égal": "ne vaut pas";
inline void A (void) {
std::cout << "X " << CHAINE << " 1" << std::endl;
}
}
int main (void) {
General::A();
return 0;
}
Tout aussi performant et avec un vrai contrôle des types.
À bientôt.
Le Farfadet Spatial
Dernière modification par Le Farfadet Spatial (Le 22/04/2008, à 21:12)
Hors ligne
#3 Le 22/04/2008, à 18:14
- geenux
Re : préprocesseur C
+1 pour la 2ème méthode
const std::string CHAINE = (X == 1)? "égal": "ne vaut pas";
J'aime la consision, mais je n'avais jamais pensé à aller jusque là dans une assignation.
Hors ligne
#4 Le 22/04/2008, à 18:27
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
J'aime la consision, mais je n'avais jamais pensé à aller jusque là dans une assignation.
C'est mon habitude à opter pour l'approche fonctionnelle qui ressort !
À bientôt.
Le Farfadet Spatial
Hors ligne
#5 Le 22/04/2008, à 19:20
- Le Farfadet Spatial
Re : préprocesseur C
Re-salut à tous !
J'y pense, puisque j'ai abordé le sujet : lorsqu'on fait de la métaprogrammation, approche fonctionnelle et opérateur trinaire sont de rigueur ! Les const et les inline également, d'ailleurs.
À bientôt.
Le Farfadet Spatial
Hors ligne
#6 Le 22/04/2008, à 20:17
- scholi
Re : préprocesseur C
en faite c'est pas juste une string que je veux afficher, c'est plutôt 10 lignes de code. Je sais que je pourrais utiliser des fonctions, c'est d'ailleurs ce que j'utilise pour l'instant, mais la version préprocesseur devrait être un poil plus rapide (et la rapidité j'en ai absolument besoin. 1/100e de seconde est important pour moi).
Donc voici un exemple fonction que je veux transformer
void a(){
plein de commande
#ifdef TRUC
fait machin
#else
fait chose
#endif
encore plein de trucs
}
en faite je crois que je viens de trouver LA solution. J'écris le tout dans un fichier a.cpp qui contient les #ifdef, #else, #endif, etc. et je fais simplement un #include "a.cpp" partout où j'en ai besoin. C'est tellement simple que je devrait me taper la tête 15 fois contre le mur...
Merci quand même bcp de votre aide
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
Hors ligne
#7 Le 22/04/2008, à 21:11
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
en faite c'est pas juste une string que je veux afficher, c'est plutôt 10 lignes de code. Je sais que je pourrais utiliser des fonctions, c'est d'ailleurs ce que j'utilise pour l'instant, mais la version préprocesseur devrait être un poil plus rapide (et la rapidité j'en ai absolument besoin. 1/100e de seconde est important pour moi).
Ça tombe bien, mon métier, c'est le calcul scientifique à hautes performances. Une branche dans laquelle un gain de 1 % en performances peut faire gagner jusqu'à quelques jours. C'est dire si la rapidité d'un code est une chose essentielle pour moi. Hé bien, mon expérience et les connaissances que j'ai pu acquérir me font dire que tu te trompes lourdement : la version avec inline est au moins aussi performante que la version avec #define. En effet, inline signifie au compilateur de recopier le code de la fonction plutôt que de générer un appel. Oui, tu as bien lu : avec inline, c'est exactement comme avec #define, le code est recopié. Tu ne gagnes donc absolument rien avec #define, par contre tu perds le contrôle des types et ça devient moins lisible est moins facile à maintenir.
Il faut t'y faire : #define, en C++, n'apporte absolument rien aux performances. Ça ne sert qu'à protéger les en-têtes (ça il faut toujours le faire) et à créer des zones de codes à ne compiler qu'en fonction de la plateforme cible --- matériel, système d'exploitation, compilateur, outils pour la construction de projet, --- ce genre de choses étant à éviter autant que faire ce peut.
Pour les performances, penche toi sur l'algorithmique et les capacités d'optimisations de ton compilateur. Un bon algorithme peut aisément te faire gagner un facteur 1000. Les options d'optimisation de ton compilateur, un facteur 100. Si tu as de la chance et que tu y passes énormément de temps, tu peux parfois gagner presque pour un facteur 10 avec des optimisations bizarres, au prix d'un temps de travail énorme, d'une perte de lisibilité, maintenabilité et portabilité du code, sachant que ces bricolages seront rapidement obsolètes. De plus, généralement, ce genre de choses dégradent les performances. Oui, tu as bien lu : lorsque l'on cherche à faire des bricolages pour optimiser un code, on le rend souvent moins efficace (et moins correct).
Décidément, il y a beaucoup de fausses idées au sujet de l'optimisation. D'ailleurs, il est temps de se rendre compte que nous ne sommes plus dans les années quatre-vingts et que les processeurs comme les compilateurs ont évolué : maintenant, pour qui veut les meilleures performances, il faut un langage de haut niveau et utiliser au mieux son compilateur. Les remarques du genre « 1/100e de seconde est important pour moi » sont l'apanage de personnes totalement déconnectées de la réalité.
Si vraiment ce sont les performances qui t'intéressent, alors je te conseille de te plonger sur un sujet qui en vaut vraiment la peine et qui t'apportera vraiment de grosses performances : la métaprogrammation et les modèles d'expressions.
À bientôt.
Le Farfadet Spatial
Hors ligne
#8 Le 22/04/2008, à 22:54
- \\Ouranos//
Re : préprocesseur C
Si tu veux de grosses performances, programme en Assembleur...
Ubuntu facile, c'est :
- Dire "Bonjour"
- Lire la doc et les règles du forum avant de poster. Savoir poser une question intelligemment.
- Mettre des balises url autour des liens et un tiret à su.
Hors ligne
#9 Le 23/04/2008, à 00:04
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
Si tu veux de grosses performances, programme en Assembleur...
Ça, c'est la fausse idée typique sortie des années quatre-vingts, aujourd'hui fausse et archi fausse.
De nos jours, les processeurs sont superscalaires --- utilisation intensives des pipelines et parallélisme intrinsèque --- et multi-cœurs (ils fonctionnent donc comme plusieurs processeurs en parallèles). De sorte que pour vraiment en tirer partie, il faut faire attention à l'utilisation des pipelines et au parallélisme. Sans parler de la nécessité d'aligner les données dans le bus. Toutes ces optimisations sont pour ainsi dire inaccessibles à l'être humain. Au contraire, la théorie de la compilation a énormément progressé, de sorte que les compilateurs font désormais ça très bien. Sans oublier d'autres optimisations délicates à mettre en place, comme le déroulement des boucles.
Bref, aujourd'hui l'assembleur ne fait plus gagner en performances. Au contraire : en général, un programme en assembleur sera moins performant qu'un programme optimisé par un compilateur. Par contre, le programme en assembleur ne sera absolument pas portable.
L'utilisation rationnelle de l'assembleur c'est de l'utiliser pour les accès directs et fins au matériel, domaine de la programmation système. Mais pour l'optimisation, ce n'est plus un outil intéressant.
À bientôt.
Le Farfadet Spatial
Hors ligne
#10 Le 23/04/2008, à 00:06
- :p
Re : préprocesseur C
Bonjour a tous,
Le farfadet je suis particulierement interessé par ce dont tu parle, aurais tu des liens pertinent a indiquer par hazard?
C'est surtout pas curiosité, mais aussi parce que j'aime bien tous ce qui touche à l'algo et l'optimisation:)
Merci
#11 Le 23/04/2008, à 01:07
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
![tongue](http://forum.edubuntu-fr.org/img/smilies/tongue.png)
Le farfadet je suis particulierement interessé par ce dont tu parle, aurais tu des liens pertinent a indiquer par hazard?
Pour découvrir l'algorithmique, un excellent livre :
Thomas H. CORMEN, Charles E. LEISERSON, Ronald L. RIVEST et Clifford STEIN, Introduction à l'Algorithmique, Cours et exercices, Dunod.
Excellent pour l'initiation, mais pas seulement : cet ouvrage est très progressif et part du niveau débutant pour aller jusqu'à des concepts intéressants pour le développeur avancé. Peut être utilisé avec profit quel que soit ton langage de prédilection et ton niveau en algorithmique.
Pour éviter de faire n'importe quoi :
Pierre WOLPER, Introduction à la calculabilité, Dunod.
Un excellent ouvrage pour la mise en pratique de l'algorithmique :
Kyle LOUDON, Maîtrise des algorithmes en C, O'Reilly
Si tu as des notions en C, il te sera utile même si tu utilises un autre langage. Attention cependant si tu utilises le C++ à ne pas faire un truc bâtard, une sorte de C with class. Notamment, tu n'as pas autant besoin des pointeurs avec le C++ qu'avec le C.
La bible de l'algorithmique :
Donald E. Knuth, The art of Computer Programing, Addison-Wesley.
À terme, il y aura sept tomes. Les trois premiers sont déjà édités, le quatrième est sorti sous forme de fascicule, les autres sont à venir.
Sur le parallélisme :
Arnaud LEGRAND et Yves ROBERT, Algorithmique parallèle, Dunod.
Sur les compilateurs :
Dick GRUNE, Henri E. BAL, Ceriel J.H. JACOBS et Koen G. LANGENDOEN, Compilateurs, Dunod.
Sur l'organisation physique des ordinateurs :
Andrew TANNENBAUM, Structured Computer Organization, Pearson Education.
Sur les calculateurs en réseaux :
Andrew TANNENBAUM, Marteen VAN STEEN, Distributed Systems, Pearson Education.
Pour découvrir la métaprogrammation en C++, ce tutoriel est bien fait : http://loulou.developpez.com/tutoriels/cpp/metaprog/
Pour aller plus loin :
David ABRAHAMS et Aleksey GURTOVOY, C++ Template Metaprogramming : Concepts, Tools, and Techniques from Boost and Beyond, Pearson Education.
Pour s'initier à l'optimisation de code :
Nicolas BOULAY, Hack en C, Linux Magazine France N° 32.
Tu peux en trouver la copie à cette adresse : http://madchat.org/coding/c/hack_processeur_en_C.html
Il est aujourd'hui complètement dépassé en ce qui concerne les capacités d'optimisation de GCC et ne parle pas de parallélisme, mais c'est une bonne introduction à l'optimisation.
Toujours au sujet de l'optimisation :
Dave FALLER, Techniques d'optimisation, Software 2.O Extra!, n° 2/2005, février/mars 2005.
Tu peux regarder le travail que j'ai fait à la fin de mon master, il s'agissait d'optimisation dans une bibliothèque de calcul scientifique. Tu trouveras le mémoire à cette adresse : http://www.legos.obs-mip.fr/~lebars/publications. Il se nomme : « Implémentation de la méthode CESTAC dans la bibliothèque BLAS. » Le truc, c'est que ce travail a déjà trois ans : il est dépassé au niveau des capacités d'optimisations des compilateurs et ne s'occupe pas du cas des processeurs multi-cœurs.
Si tu as besoin de te remettre à jour sur les notions mathématiques abordées, voici quelques ouvrages :
René CORI et Daniel LASCAR, Logique mathématiques, Dunod, 2 tomes.
Gilles CHRISTOL, Anne COT et Charles-Michel MARLE, Topologie, Ellipses.
Georges GRAS et Marie-Nicole GRAS, Algèbre fondamentale, Arithmétique, Ellipses.
Avec tout ça, je pense que tu as déjà de quoi bien t'amuser ! En tout cas, voilà l'essentiel de ce qui se trouve dans ma bibliothèque personnelle au sujet de l'algorithmique et de l'optimisation.
À bientôt.
Le Farfadet Spatial
EDIT : encore quelques ouvrages.
Dernière modification par Le Farfadet Spatial (Le 23/04/2008, à 01:56)
Hors ligne
#12 Le 23/04/2008, à 08:04
- _YokoUno
Re : préprocesseur C
Merci pour cette biblio
Puisque tu sais de quoi tu parles, j'aimerais ton avis sur un truc:
Il y a quelques années, j'ai été obligée de faire de l'optimisation à la main de calculs flottants, en assembleur 80x87. Les gains de perfs avaient été spectaculaires, mais ça reste un souvenir pénible
La décision de descendre au niveau assembleur avait été prise après avoir remarqué que mon compilo était particulièrement stupide dans l'utilisation de la pile du x87, même avec les options d'optim à fond. En gros, il faisait des load/save superflus depuis/vers la mémoire, et n'effectuait que rarement les calculs en place, à l'intérieur de la pile STx, qui comme tu le sais est une pile finie.
Je suis curieuse de savoir si les compilateurs actuels, gcc et autres, sont devenus intelligents vis à vis de ces mouvements de pile. Sont-ils désormais capables de trouver un ordre optimal ainsi que peut le faire un humain?
#13 Le 23/04/2008, à 09:02
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
Je suis curieuse de savoir si les compilateurs actuels, gcc et autres, sont devenus intelligents vis à vis de ces mouvements de pile. Sont-ils désormais capables de trouver un ordre optimal ainsi que peut le faire un humain?
La réponse courte est oui.
Même souvent mieux qu'un humain. Enfin, ça va dépendre du compilateur, mais un compilateur commercial ou GCC font ça, en général. Ils peuvent même faire mieux qu'un être humain.
Après, le problème c'est que trouver l'ordre optimal est un problème NP-complet (si je ne m'abuse). Donc, on ne peut pas garantir que l'ordre soit optimal, simplement qu'il sera plutôt bon. Cela dit, un être humain ne peu pas prétendre, non plus, garantir de trouver l'ordre optimal.
Les compilateurs ont beaucoup évolués. Notamment GCC, avec le passage à la version 4.0 et il continue d'évoluer vers de meilleures performances. Ça vaut le coup de se renseigner sur ses évolutions. LLVM est à surveiller également.
Bien sûr, encore maintenant, de façon extrêmement ponctuelle (il faut voir au cas par cas), il peut arriver qu'il soit plus efficace de faire les choses à la main. Cependant, les choses évoluent très vite, ce qui fait qu'en peu de temps les manques des compilateurs sont comblés. De plus, les optimisations à la main deviennent très vite obsolètes.
En tout cas, si vraiment on se retrouve dans un cas où il est intéressant de faire des optimisations à la main, il est bon de contacter les équipes de développement des compilateurs : on obtiendra de l'aide et cela peut faire évoluer le compilateur.
À bientôt.
Le Farfadet Spatial
Hors ligne
#14 Le 23/04/2008, à 10:24
- Le Farfadet Spatial
Re : préprocesseur C
Re-salut à tous !
Hop, je reviens. D'abord pour repréciser le message précédent : je ne peux pas garantir que le compilateur fera toujours ce qu'il y a de mieux, par contre je peux dire que ce sera généralement le cas. Si vraiment on voit apparaître une chute de performance sensible, alors on peut commencer à se demander si... on ne pourrait pas contacter les développeurs du compilateur.
Sinon, au niveau de l'optimisation, on se retrouve souvent à se poser des questions relatives à la théorie des graphes. Sur ce sujet :
Claude BERGE, Graphes, Gauthier-Villars.
Claude BERGE, Hypergraphes, Gauthier-Villars.
Un ouvrage général sur les mathématiques, en cas de besoin :
Elie AZOULAY, Jean AVIGNANT et Guy AULIAC, Mathématiques, cours et exercices résolus, Ediscience international, 4 tomes.
À bientôt.
Le Farfadet Spatial
Hors ligne
#15 Le 23/04/2008, à 13:07
- :p
Re : préprocesseur C
merci pour tous
J'ai de quoi lire cet été sur la plage
#16 Le 23/04/2008, à 14:06
- _YokoUno
Re : préprocesseur C
Merci pour ta réponse
Je n'avais pas employé l'adjectif "optimal" au sens mathématique, mais c'est pas plus mal que tu l'aies compris ainsi...
De toute manière, il est manifeste que la solution n'est pas forcément unique.
Et dans les faits, quand on optimise à la main on fait ça à la louche de toute façon: on sait qu'il est déraisonnable d'essayer de gratter 3 cycles quand on a déjà serré les boulons pour arriver à 400.
A moins d'être maso, d'avoir du temps, ou d'avoir de bons restes d'hp48
Qu'un compilo arrive à atteindre une solution sous-optimale de ce genre, c'est déjà très bien je trouve.
#17 Le 25/04/2008, à 12:52
- Nicolasbo
Re : préprocesseur C
La décision de descendre au niveau assembleur avait été prise après avoir remarqué que mon compilo était particulièrement stupide dans l'utilisation de la pile du x87, même avec les options d'optim à fond. En gros, il faisait des load/save superflus depuis/vers la mémoire, et n'effectuait que rarement les calculs en place, à l'intérieur de la pile STx, qui comme tu le sais est une pile finie.
Gcc fait cela pour respecter IEEE754. Intel fait des calculs sur 80 bits pour un double en utilisant la pile, AMD le fait pour 64 bits uniquement. La différence de manière de calculer fait des différences d'arrondis. Le fait d'écrire en mémoire tronque la valeur comme il faut.
Si tu veux des perfs en te foutant de ce genre de problème utilise --fast-math.
Il est possible aussi que GCC est du mal avec une pile qui n'est pas un banc de registre et rajouter des mouvements de registres pour rien.
L'article "hack en C" peut se trouver ici:
http://chl.be/glmf/articles.linuxmag-france.org/lm32/hackC.html
#18 Le 26/04/2008, à 01:44
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
Nicolasbo... Ça me dit quelque chose... Surtout qu'il sait fort bien où retrouver cet article...
Alors, mon cher Nicolabo, fais-je erreur ?
À bientôt.
Le Farfadet Spatial
Hors ligne
#19 Le 26/04/2008, à 18:08
- NicolasBo
Re : préprocesseur C
Diantre, je suis découvert.
Je voulais juste éviter de faire mon auto-pub
#20 Le 26/04/2008, à 19:14
- Le Farfadet Spatial
Re : préprocesseur C
Salut à tous !
Diantre, je suis découvert.
Je le savais, rien n'échappe à mon impressionnante clairvoyance !
Cela dit, ça fait plaisir, depuis le temps que nous n'avons pas été en contact (c'est pas mal de ma faute). Je ne savais pas que tu étais sous Ubuntu maintenant.
À bientôt.
Le Farfadet Spatial
Hors ligne
Pages : 1