Écrit à l'origine par Richard Stallman, le logiciel GCC (GNU Compiler Collection) est le compilateur de référence du monde du logiciel libre. Il accepte des codes source écrits en C, C++, Objective-C, Fortran, Java et Ada et fonctionne sur une multitude d'architectures.
Dans la suite de la dépêche, vous pourrez découvrir les nouveautés et les optimisations mises en œuvre dans cette version 4.5 de GCC ainsi qu'un entretien avec Basile Starynkevitch, employé par le CEA, développeur du greffon MELT et contributeur de GCC. Merci à lui pour avoir pris le temps de répondre à mes questions et merci également à Laurent Guerby pour sa relecture de la dépêche et pour ses suggestions.
Le sommaire...
Optimisation lors de l'édition des liens (↑)
Les étapes d'une compilation
Une grande nouveauté de GCC 4.5 est l'introduction de la technique d'optimisation lors de l'édition des liens (Link Time Optimization). Pour mieux comprendre de quoi il s'agit, il faut savoir que lors de la compilation d'un programme ce sont en fait plusieurs étapes qui se déroulent successivement.Dans la première étape, la compilation proprement dite, GCC lit les fichiers sources compréhensibles par un humain, écrits par exemple en C, et transforme le source en une représentation intermédiaire nommée GIMPLE. Quand il est ainsi traduit, le code source est plus facile à optimiser. Une fois toutes les passes d'optimisation terminées, GCC va créer à partir de ces fichiers sources optimisés les fichiers correspondants contenant des instructions que seul le processeur peut comprendre. Ces fichiers en sortie sont nommés les "fichiers objet".
Lors de l'étape finale, nommée édition de liens, GCC va "combiner" entre eux tous ces fichiers objets pour faire un seul exécutable. C'est aussi dans la phase d'édition des liens que les appels de fonction de votre code sont remplacés par les instructions correspondantes qui viennent des fichiers pré-compilés d'une ou plusieurs bibliothèques.
On a donc le trajet suivant :
Fichiers de code source → Optimisation → Fichiers objet → Fichier unique exécutable.
Une optimisation supplémentaire
Une fois ce rappel effectué on comprend mieux la motivation qui se cache derrière la fonction d'optimisation lors de l'édition des liens (LTO pour Link Time Optimization). Dans la procédure précédente vous avez noté que l'optimisation se fait avant la "fusion" des fichiers objets dans l'exécutable. Mais on peut penser que si le compilateur avait une idée globale du programme, de tous les fichiers sources à la fois, alors il pourrait sans doute trouver des optimisations supplémentaires par rapport à celles qu'il fait sur chaque fichier pris individuellement. Lors de l'édition des liens le compilateur a une visibilité parfaite sur toutes les fonctions et sur le flux de données complet et il est donc potentiellement intéressant d'ajouter une phase d'optimisation à ce stade.Pour implémenter cette belle idée (qui existe sur d'autres compilateurs depuis plusieurs années) GCC 4.5 va lors de la compilation inscrire du code intermédiaire GIMPLE dans certaines sections spéciales du fichier objet (qui est donc un peu plus gros que d'habitude). De cette façon ce code GIMPLE peut être lu lors de l'étape finale d'édition des liens et servir à optimiser globalement le programme.
On a donc le trajet suivant :
Fichiers de code source → Optimisation → Fichiers objet → Optimisation → Fichier unique exécutable.
Une flexibilité supplémentaire
En plus du gain prévisible en performances du fait de l'arrivée des optimisations globales il y a aussi un gain en flexibilité. Ainsi GCC 4.5 pourra, grâce à LTO, optimiser globalement un programme qui rassemble des fichiers sources écrits dans des langages différents (un fichier en C, un autre en C++ et un troisième en Fortran par exemple) :gcc -c -O3 -flto fichier1.c (optimise le fichier individuel écrit en C).
g++ -c -O3 -flto fichier2.cc (optimise le fichier individuel écrit en C++)
gfortran -c -O3 -flto fichier3.f90 (optimise le fichier individuel écrit en Fortran)
g++ -o progfinal -flto -03 fichier1.o fichier2.o fichier3.o -lgfortran (optimise globalement le programme final).
Il est aussi possible d'optimiser différemment les fichiers individuels et le programme final :
gcc -c -Os -flto fichier1.c fichier2.c (optimise les fichiers individuels pour la taille).
gcc -o progfinal -flto -O3 fichier1.o fichier2.o (optimise le fichier final pour les performances).
Bien entendu l'optimisation finale, celle qui porte sur tous les fichiers à la fois, est susceptible d'utiliser une grande quantité de mémoire et de générer une forte charge processeur. C'est pour résoudre ce problème épineux qui menaçait de rendre la technique LTO impraticable que les développeurs ont proposé l'architecture WHOPR (WHOle Program OptimiseR).
On utilisera ainsi l'option -fwhopr au lieu de -flto et le changement est radical ! Avec -flto toutes les fonctions de tous les fichiers sont chargées en mémoire ce qui risque de la saturer. Avec -fwhopr on utilise le graphe des appels de fonction qui est d'abord analysé puis partitionné pour pouvoir être distribué entre les processeurs. Plus besoin de tout charger en mémoire en une seule fois puisque le travail à faire a été décomposé en unités plus petites.
Le projet WHOPR tente donc de paralléliser au maximum le travail et le fichier pdf de compte-rendu indique que le graphe d'appel des fonctions (call-graph) peut maintenant atteindre un million de nœuds et un million d'arêtes et néanmoins tenir en moins de 500 Mo de RAM.
Le bilan
Alors quels sont les résultats de tout ce travail ? Et bien il faut bien dire que, si l'on en croit les tests publiés, la technique LTO est certes intéressante mais pas encore révolutionnaire. Le travail a commencé il y a bien longtemps (voir ce fichier pdf de 2005) mais le monde des compilateurs est notoirement complexe et les performances ne progressent que doucement. Certes l'infrastructure LTO est en place mais pour l'instant les passes spéciales d'optimisations globales sont encore rares et rudimentaires. En allant voir les chiffres bruts sur les machines de tests disponibles sur cette page nous pouvons voir (à la date du 12 avril) que les scores sont les suivants sur la machine Barbarella qui est un quadri-cœurs AMD :Options de compilation : -O3 -funroll-loops -fpeel-loops -ffast-math -march=native
SPECfp2006 base : 9.6
Options de compilation : -O3 -funroll-loops -fpeel-loops -ffast-math -march=native -flto -fwhole-program
SPECfp2006 base : 10.5
Avec l'option -flto le score est donc quasi égal.
Options de compilation : -O3 -funroll-loops -fpeel-loops -ffast-math -march=native
SPECint2006 base : 10.8
Options de compilation : -O3 -funroll-loops -fpeel-loops -ffast-math -march=native -fwhopr -fwhole-program
SPECint2006 base : 18
Avec l'option -fwhopr (plus efficace que -flto sur les entiers) on voit un gain assez significatif du fait de l'optimisation globale.
J'ai posé par mail la question des performances aux administrateurs de la ferme de test GCC d'OpenSuse et voici la réponse de Richard Guenther :
"Bon le résultat encourageant c'est que ça fonctionne la plupart du temps ;)
Il y a aussi une réduction significative de la taille du code tout en ayant des performances égales ou même un peu meilleures.
Notez qu'aucun travail n'a encore été fait pour analyser ou trouver les optimisations manquantes. En conséquence c'est vrai que LTO dans GCC 4.5 est plus un aperçu et une base pour les développements ultérieurs".
L'arrivée des greffons (↑)
Pourquoi des greffons ?
La seconde grande nouveauté de GCC 4.5 est l'arrivée de la fonction d'ajout de greffons (ou plugins).GCC est un compilateur multi plates-formes très puissant mais, au fil des années, son code est devenu complexe et intimidant (plus de 4 millions de lignes selon sloccount). L'ajout d'une fonction peut impliquer une réécriture d'une partie importante du code et cette situation n'est, on s'en doute, pas optimale. Un peu de modularité serait appréciable !
L'introduction des greffons semble donc une solution logique mais cette fonctionnalité n'a été accueillie que fort prudemment par la FSF (qui possède le copyright de GCC).
La Free Software Foundation a pour mission de promouvoir le logiciel libre et il était important de veiller à ce que les greffons de GCC ne puissent pas être utilisés pour retirer des libertés aux utilisateurs.
La Runtime Library Exception de GCC a donc été modifiée (le passage en GPLv3 est aussi une des raisons de cette modification) et l'architecture des greffons a pu entrer sans risque juridique dans le projet.
Comme l'a également souligné Basile Starynkevitch lors de la conférence Parinux du 12 janvier, les greffons sont nécessairement libres mais ils ne nécessitent pas d'attribution de copyright à la FSF. De nombreuses entreprises sont réticentes à signer les documents juridiques de la FSF d'attribution de copyright et on peut donc espérer que la possibilité d'écrire un greffon sans passer sous les fourches caudines de la FSF incitera plus d'entreprises à contribuer à l'écosystème du compilateur libre.
La mission des développeurs est également d'éviter les risques techniques et le travail a donc été très soigneux sur l'interface entre le corps de GCC et les différents greffons. Une comparaison détaillée des différentes interfaces envisageables a été effectuée et une API propre a été choisie.
La modification de l'architecture globale de GCC pour autoriser les greffons permet d'introduire une grande souplesse dans son architecture. Un ajout de fonction peut maintenant se faire avec une simple option -fplugin=MonGreffon.
Cela va charger la bibliothèque dynamique MonGreffon.so dans GCC et vous pourrez ensuite utiliser le greffon lors de vos compilations.
Seulement un début
Nul doute que la flexibilité offerte par ce nouveau système modulaire va attirer de nouveaux développeurs et donc favoriser les innovations. La communauté du libre ne pourra qu'en bénéficier à long terme même si, bien entendu et comme pour la fonction LTO qui a été détaillée plus haut, l'histoire ne fait que commencer et il existe encore peu de greffons pour GCC.Dans ce domaine on peut citer :
- Dehydra et Treehydra sont des greffons d'analyse statique du code développés par Mozilla pour ses besoins particuliers.
Une présentation pdf issue du sommet GCC 2008 est disponible et un article LWN a récemment été consacré à ces greffons.
- DragonEgg est un greffon qui remplace le frontal LLVM-GCC et sert donc à générer du code pour alimenter le compilateur libre concurrent LLVM.
- ICI (Interactive Compilation Interface) implémente une série de greffons issus du réseau académique HIPEAC comme par exemple des fonctions d'apprentissage automatique (voir le projet de recherche MILEPOST et ce fichier pdf explicatif).
- MELT (pour Middle End Lisp Translator) est un greffon écrit par Basile Starynkevitch et qui sert à implémenter des passes d'optimisation dans un langage de haut niveau proche de Lisp. On peut ainsi faire du prototypage rapide d'idées ayant vocation à rejoindre plus tard GCC ou bien on peut écrire des passes spécialisées pour des projets particuliers. La syntaxe de haut niveau facilite le travail par rapport à un greffon écrit en C.
Au sujet de MELT et de GCC en général j'ai posé quelques questions à Basile le 13 janvier dernier (donc bien avant la sortie de GCC 4.5 qui, à cette date, était seulement en période de freeze).
Questions/Réponses avec Basile Starynkevitch (↑)
Ante-scriptum : les réponses ici n'engagent que moi et ne sont que mon opinion à moi, Basile Starynkevitch, pas celle de mon employeur, des financeurs de mon travail, de la communauté GCC, de la FSF, April ou toute autre organisation.
patrick_g : Quelles ont été les réactions envers MELT en particulier et les greffons en général (sur les listes de diffusion ou ailleurs) ? Est-ce une fonctionnalité très attendue de GCC ?
Basile : Je comprends la question comme concernant les réactions sur les listes GCC, pas seulement à mon exposé de mardi à Parinux.
Sur les greffons (plugins) de GCC 4.5 et le mécanisme de greffons en général, il y a trois sortes d'attitudes au sein de la communauté développant GCC :
* La plupart ne se sentent pas concernés du tout. Les greffons n'intéressent pas la majorité des développeurs de GCC (et c'est à mon avis bien normal : une fois le mécanisme existant, ce sont des gens extérieurs à la communauté GCC qui développeront des greffons.
* Quelques acteurs sont moteurs et contribuent ou ont contribué du code en rapport avec les greffons. En particulier plusieurs employés de Google travaillent activement à ce sujet, et aussi plusieurs personnes du secteur académique (INRIA) ou recherche appliquée (dont moi).
* Quelques contributeurs à GCC expriment une franche hostilité au principe même des greffons dans GCC, en argumentant qu'ils introduisent une complexité supplémentaire (c'est très peu vrai) et qu'ils vont fragmenter, disperser et fragiliser la communauté (je parie que non).
Sur MELT en particulier, il y a généralement un silence bienveillant, et parfois une curiosité intéressée. J'ai probablement péché par manque de communication (mais son développement prend du temps). Je travaille sur un tutoriel (en plus des pages embryonnaires existantes). Pour que MELT ou tout autre greffon expérimental (TreeHydra, ICI, DragonEgg, ...) ait des utilisateurs externes, il faut que GCC 4.5 soit sorti (En pratique, les branches expérimentales de GCC sont peu utilisées, et même une version nouvelle de GCC met parfois plusieurs années à être adoptées par les développeurs : dans le monde de l'embarqué, certains utilisent encore une version de GCC d'il y a dix ans ; dans les systèmes Linux, on utilise souvent une version d'il y a plusieurs années !).
Sur les greffons eux-mêmes en général, il est beaucoup trop tôt pour mesurer une réaction; en effet, GCC 4.5 n'est pas encore sorti. En pratique, personne d'extérieur à la communauté n'a conscience de l'existence des greffons expérimentaux déjà prototypés (et dont on ne connait pas leur avenir, quand GCC 4.5 sera paru).
Par définition même des greffons, aucune passe interne à GCC ne les utilise ; c'est tout le contraire : un greffon ajoute (ou enlève, ou réordonne) des passes dans GCC. Les greffons sont totalement facultatifs et GCC 4.5 fonctionnera très bien – et même habituellement – sans aucun greffon chargé. Tout greffon doit être compilé pour une version spécifique de GCC. Ainsi, un greffon pour GCC 4.5.0 devra être recompilé pour tourner avec 4.5.1, et son code source devra sûrement être modifié pour le futur GCC 4.6.0.
Je pense et j'espère que les greffons auront du succès, en particulier parce que :
1. (point mineur, mais pratiquement significatif) Un greffon doit être libre sous licence GPLv3 (ou compatible), mais ne doit pas nécessairement – au contraire du cœur de GCC – être sous copyright FSF (comme GCC l'est). Il est juridiquement beaucoup plus facile, quand on veut commencer à travailler dans GCC, de proposer un greffon que d'avoir préalablement obtenu l'autorisation de ce transfert de copyright, nécessaire même pour proposer un petit patch de cinq lignes à GCC.
2. principalement, les greffons serviront, je l'espère, à ajouter dans GCC des traitements spécifiques à un logiciel particulier (compilé par GCC) : ces traitements spécifiques n'intégreront jamais le cœur de GCC.
patrick_g : Outre le greffon MELT lui-même est-ce qu'il existe déjà des passes qui l'utilisent afin d'apporter des fonctions ?
Basile : GCC 4.5 n'est pas encore sorti au 13 janvier 2010. Il n'y a donc actuellement aucun greffon de GCC utilisé réellement, et MELT ne sera pas immédiatement le greffon le plus populaire.
Je vais utiliser MELT (et continuer de l'améliorer) au sein du projet OpenGPU (projet de R&D multi-partenaire financé par appel d'offre étatique en France), où mon rôle sera de générer du code OpenCL (pour calculs numériques sur cartes graphiques) et d'aider à détecter le code qui pourrait y tourner.
MELT doit être vu comme un méga/méta-greffon de GCC. C'est pratiquement un outil pour coder des traitements spécifiques, qu'on pourrait péniblement coder comme des greffons directs de GCC en C, mais qu'on gagne à coder en MELT dans un module (MELT est un greffon de GCC qui traduit du code MELT en du code C, lui-même compilé en un module puis chargé par GCC/MELT).
Les traitements des greffons de GCC (ou des modules codés en MELT) seront spécifiques à un gros logiciel compilé par GCC (par exemple le noyau Linux, les environnements graphiques Qt/KDE ou GTK/Gnome, le serveur Apache et ses modules, le navigateur Firefox, les suites bureautiques Abiword ou OpenOffice.org, et tout autre gros logiciel sur lequel des efforts de génie logiciel, de méthodologie, d'outillage de développement sont bienvenus). Une entreprise (ou une communauté) développant un assez gros logiciel patrimonial (d'au moins plusieurs centaines de milliers de ligne de code source) devrait avoir une personne responsable de la méthodologie, de l'architecture, de l'outillage en génie logiciel, des règles de codages, et cette personne a intérêt à développer ou faire développer un greffon de GCC (par exemple un module de MELT). Les traitements spécifiques d'un greffon de GCC ou d'un module de MELT peuvent par exemple être :
1. Des diagnostics spécifiques, par exemple simplement trouver les fonctions C qui font un fopen sans en tester le résultat, ou appellent gtk_calendar_freeze sans appeller gtk_calendar_thaw (je sais que ces fonctions sont obsolètes en GTK 2.14, mais c'est juste un exemple).
2. Certaines optimisations spécifiques par exemple fprintf(stdout,....) peut être réécrit en printf(...) etc. On pourrait peut-être le faire de manière textuelle (en awk ou ed ou perl etc.) mais dans GCC, ça sera fait après inlining, ce qu'on ne pourrait pas faire en dehors de GCC.
3. Validation du respect des règles de codage spécifiques.
4. Aide à la rétro-ingénierie, refactoring et métriques, voire programmation par aspects (ajouter un test devant chaque appel à telle fonction dont le premier argument est non nul).
5. Tout et n'importe quoi d'autre.
Il est important de noter qu'il faut être spécialiste du gros logiciel visé (GTK ou autre) pour définir et implémenter ce genre de traitement, qui étant spécifique à ce logiciel ne sera jamais au cœur de GCC. Il faut aussi comprendre un peu les internes de GCC, puis coder le greffon. MELT est alors utile : les difficultés liées à la complexité du logiciel visé et aux représentations internes de GCC demeurent, mais MELT facilite le codage d'un tel traitement en apportant des traits de haut niveau (filtrage ou pattern matching, programmation fonctionnelle, programmation objet), tout en collant et en s'adaptant à l'évolution de GCC. Un code MELT est bien plus concis que son équivalent en C : les 33KLOC du traducteur MELT sont traduits en 560KLOC de C généré.
Je suggère à des étudiants ambitieux ou à des libristes passionnés de contribuer de tels traitements spécifiques.
Je ne peux pas vous coder vos traitements spécifiques (il faut bien connaître le logiciel visé) mais je peux vous aider à apprendre et à utiliser MELT, peut-être même vous former un peu à MELT.
patrick_g : Pourquoi une syntaxe basée sur Lisp ? Si un contributeur veut implémenter une syntaxe alternative est-ce "facile" ?
Basile: Il existe des livres, une tradition (Emacs-Lisp, Guile, Scheme), des modes Emacs ou Vi... une puissance des macros autour de Lisp. Et la pauvreté de la syntaxe parenthésée de Lisp la rend facile car systématique. Je me rends compte qu'il y des gens allergiques aux parenthèses, et je suis en train de définir et d'implémenter une syntaxe infixe [inspirée par le style de Pascal, Javascript, Ocaml] d'un très large sous-ensemble de MELT pour ceux-ci. Si vous connaissez Lisp et êtes enthousiastes pour le faire à ma place dites le moi vite. Mais je ne pourrais développer ni mode Emacs, ni indenteur, ni pretty-printer pour les deux syntaxes (Lispienne ou infixe) de MELT. Toute aide est bienvenue.
patrick_g : Quel est l'avantage technique de faire, par exemple, de l'analyse statique de code dans un greffon GCC plutôt que dans un logiciel externe ?
Basile : Il existe d'excellents logiciels d'analyse statique, y compris en libre, par exemple Frama-C (LGPL, codé en Ocaml – qui peut en particulier prouver que le code C suit ses spécifications convenablement formalisée en ACSL dans des commentaires). Certains sont très puissants mais peuvent être difficiles à utiliser. De toutes manières, développer un outil d'analyse statique est très difficile, et juste l'utiliser n'est pas trivial.
L'avantage de coder un greffon dans GCC, c'est :
* Une fois développé et installé, un greffon est très facile à utiliser; on ajoute -fplugin=greffon.so à ses drapeaux CFLAGS de compilation. Ça ne perturbe pas l'utilisateur.
* Pour coder un greffon, on dispose de toute la puissance de GCC. En particulier, des représentations internes puissantes, des transformations déjà effectuées (optimisations). Un compilateur est avant tout un malaxeur de représentations internes (arborescentes ou en graphe parfois cyclique), ce n'est pas un transformateur textuel.
* Pour des optimisations spécifiques à un logiciel, il faut travailler à l'intérieur de GCC.
* Mais GCC est complexe. Il faut en comprendre (en partie) les représentations internes et les passes. Une fois qu'on a compris ces bases, MELT permet une plus grande productivité.
Par exemple, il est facile d'imaginer qu'une distribution Linux utilise des greffons de GCC. Il lui serait plus difficile d'utiliser un analyseur statique externe !
patrick_g : Comment est-ce que tu vois le projet LLVM/CLang ? Est-ce que GCC est menacé ?
Basile : LLVM est très intéressant, en particulier pour ceux qui veulent générer du code binaire dans leur application (c'est d'abord une bibliothèque C++ conçue pour ça). Clang est un compilateur C & C++ au dessus de LLVM. Pour l'instant, il est un peu moins performant (voir tests sur Phoronix). Mais GCC est un mastodonte (4MLOC), qui n'est pas encore prêt d'être détrôné et qui croît encore (30% de croissance en 2 ans).
je déplore d'ailleurs que des langages compilés de plus haut niveau soient aussi peu utilisés. En particulier, Ocaml comme Common Lisp sont des excellents langages (et ils seraient plus adaptés pour écrire un gros compilateur que ne l'est C ou C++).
GCC va exister encore longtemps. Beaucoup de logiciels (notamment le noyau Linux) en dépendent fortement. Je trouve la compétition (notamment avec LLVM) saine et bénéfique.
patrick_g : Qu'est-ce qui t'énerve particulièrement dans GCC ?
Basile : Comme dans toute grosse communauté logicielle, c'est la difficulté à faire approuver mes soumissions de patch. Aussi, son énormité, et le fait un peu paradoxal que beaucoup de ses contributeurs connaissent trop peu à mon goût les langages de programmation de haut niveau.
patrick_g : Si tu devenais demain le "dictateur bienveillant" du projet quels seraient tes changements ?
Basile : Je refuserais le poste. La fonction est impossible, c'est pour ça qu'il n'y en a pas. Tout code soumis dans GCC doit être revu par autrui. GCC montre qu'un gros logiciel peut être développé sans management fort. L'espèce humaine n'a pas les capacités de management que certains imaginent. Le développement de GCC est organique, il croit comme en embryon. C'est très bien comme ça.
Informations diverses :
MELT est disponible comme une branche, et sera un greffon dès l'apparition de GCC 4.5.
Je suis disposé à vous aider à coder vos modules en MELT pour les traitements spécifiques à vos applications. Mais je ne peux pas les coder à votre place.
patrick_g : Merci beaucoup pour tes réponses.
D'autres nouveautés de GCC 4.5 en bref (↑)
- Le support de l'architecture Itanium1 (nom de code Merced) a été retiré de GCC 4.5. Non seulement le code compilé pour Itanium2 fonctionne correctement et devrait suffire à tous mais il est de plus fort probable que plus personne n'utilise aujourd'hui cette première génération d'Itanium qui fut fort décevante.
- Toujours coté support les processeurs de la famille Intel Atom ont maintenant leurs options d'optimisations spécifiques avec -march=atom et -mtune=atom. Une possibilité de différenciation qui s'ouvre pour les distributions Linux spécialisés dans les netbooks.
- Dans une autre catégorie de performances que les Atom, une autre catégorie de prix également, GCC 4.5 permet d'optimiser son code pour le surpuissant POWER7 d'IBM (-mcpu=power7 et -mtune=power7). Rappelons que le POWER7 est un processeur comprenant 8 cœurs quadri-threads cadencés à 4 GHz environ (avec un "modeste" cache L3 de 32 Mo intégré directement sur la puce !). Nous en reparlerons sans doute dans une future dépêche Top500 car la machine Blue Waters, 20 pétaflops en 2011, se basera sur ce monstre.
- Le projet Moxie visant à définir une nouvelle architecture virtuelle et qui est détaillé dans une série de messages sur ce blog est devenu un port officiel dans GCC 4.5. Moxie est une intéressante expérience puisque Anthony Green, son développeur, a essayé de créer un jeu d'instruction pour processeur, une ISA, qui soit adapté dès le départ aux exigences du compilateur (approche top-down) au lieu de commencer par le matériel et de se débrouiller ensuite comme on peut avec le compilateur (approche bottom-up).
- L'option -save-temps de GCC (qui conserve les fichiers intermédiaires du processus de compilation) accepte maintenant d'écrire ces fichiers dans un répertoire spécifié en option. Cela permet de lancer des compilations en parallèle sans risquer des collisions de noms lors des enregistrements des fichiers intermédiaires.
- L'option -fexcess-precision fait son entrée dans la longue liste des fonctions de GCC. Avec elle vous pourrez contrôler la gestion des arrondis sur les nombres flottants. Avec -fexcess-precision=fast on utilise la précision des registres du processeur alors qu'avec -fexcess-precision=standard on se conforme strictement à la norme ISO C99 (et le code est souvent plus lent).
- Après l'entrée de la bibliothèque de gestion des nombres flottants MPFR dans la version 4.3 c'est maintenant la bibliothèque de gestion des nombres complexes MPC qui arrive dans GCC 4.5 en tant que dépendance obligatoire. MPC va permettre d'éviter certains bugs d'arithmétique complexe et ce quelque soit la plate-forme sous-jacente.
- Sur les processeurs ARM le compilateur GCC 4.5 prend désormais en charge les nombres flottants en demi-précision (sur 16 bits au lieu de 32 pour le classique float). Ce format, défini dans la norme IEEE 754-2008 et utilisable avec le type __fp16, est utilisé pour des besoins d'économie lors du stockage de données et pas pour des calculs arithmétiques.
- Vous avez la mauvaise habitude de faire des goto en C sans penser à initialiser vos variables ? GCC 4.5 a pensé à vous et l'utilisation de l'option -Wjump-misses-init générera désormais un avertissement si vous persistez dans vos exécrables pratiques. Bien entendu, et comme son nom l'indique, il suffira d'utiliser le très sévère -Wall pour profiter de cette surveillance renforcée.
- De manière générale un gros travail a été effectué sur les avertissements émis par GCC 4.5 concernant le code C qui sont plus nombreux et plus complets. On peut citer par exemple l'option -Wc++-compat (elle alerte sur le code ne faisant pas partie du sous-ensemble commun entre le C et le C++) et qui vérifie maintenant bien plus de choses.
- Après le ralliement d'AMD au nouveau jeu d'instruction vectoriel 256 bits AVX d'Intel à la place de son extension SSE5 il restait quand même quelques instructions orphelines. Ces malheureuses n'avaient pu trouver refuge dans AVX et AMD a donc dû les extraire d'un SSE5 mort-né pour en faire simplement des instructions complémentaires d'AVX. Avec GCC 4.5 il est donc possible d'utiliser dès maintenant dans vos compilations l'option -mfma4 (une multiplication et une addition en un seul cycle) et l'option -mxop (diverses rotations et permutations de vecteurs). Ces jeux d'instructions, ainsi que l'option -mlwp qui propose des fonctions de profilage (LightWeight Profiling), seront disponibles dans les futurs processeurs AMD de la famille Bulldozer.
- Le support des versions modernes du langage Fortran s'améliore, que ce soit coté Fortran 2003 ou bien Fortran 2008, et on note de nombreuses nouvelles fonctions. Par exemple le début du support du polymorphisme et plus généralement du paradigme orienté objet dans gfortran ou encore l'usage d'arguments complexes avec les fonctions TAN, SINH, COSH, TANH, ASIN, ACOS, etc.
- En ce qui concerne la prise en charge de la future norme ISO C++0x, le travail avance comme à chaque version et GCC 4.5 renforce encore la compatibilité avec ce nouveau standard. Les nouvelles fonctions de ce C++ rénové sont activables avec -std=c++0x et les progrès peuvent être suivis sur la page spéciale consacrée à C++0x du site GCC.
- L'instanciation des templates C++ se fait maintenant avec une table de hachage pour gagner en rapidité de compilation. Auparavant le temps de compilation était en progression quadratique alors que maintenant la progression n'est plus que linéaire. GCC 4.5 rejoint ainsi sur ce point le compilateur LLVM/Clang et on ne verra plus des comportements pathologiques tels que celui-ci.
- La détection des débordements de pile dans les programmes écrits en langage Ada est maintenant fonctionnelle avec GCC 4.5. Dans certains cas spécifiques la détection peut laisser passer le débordement potentiel mais un avertissement est quand même émis lors de la compilation, ce qui permet d'alerter le programmeur.
- Le processeur LatticeMicro32, qui est une puce programmable simplifiée de type FPGA, devient un port officiel dans GCC 4.5. Ce cœur RISC est utilisé notamment dans le SoC (System-on-Chip) sous licence GPL du projet Milkymist évoqué dans le numéro 124 de GNU/Linux Magazine France. A noter que c'est le créateur du projet Milkymist, Sébastien Bourdeauducq, qui a fait la demande d'inclusion du port sur la liste de diffusion de GCC.
- Sur la lancée de GCC 4.4, qui améliorait significativement la prise en charge de l'architecture MIPS, cette nouvelle version du compilateur du projet GNU ajoute elle aussi beaucoup de choses. On retrouve la gestion du processeur MIPS 1004K (multicœur et multithread), la possibilité d'optimiser séparément les modes 32 et 64 bits, la meilleure gestion des caches, la possibilité de transformer des appels indirects pour les rendre plus rapides, l'optimisation du code généré spécifiquement pour les processeurs Octeon, la meilleure prise en charge des fonctions servant à la gestion des interruptions, etc. Au chapitre sécurité on note que le support de la commande -fstack-protector, qui permet de contrer les attaques par débordement de la pile, est maintenant disponible sur MIPS.
- Avec cette nouvelle version 4.5 les fichiers d'en-têtes (headers) qui sont appelés dans un #include et qui ne sont pas trouvés lors de la compilation entraînent un arrêt immédiat de GCC. On évite ainsi la litanie des messages d'erreurs successifs que cela entraînait auparavant.
- La fonction de parallélisation des boucles de code, activable avec -ftree-parallelize-loops, est désormais utilisable par l'infrastructure d'optimisation Graphite (détaillée dans la dépêche sur GCC 4.4). Pour profiter simultanément de l'optimisation Graphite et de la parallélisation de boucles il faut passer l'option -floop-parallelize-all au compilateur.
- Plus généralement si on veut avoir une vue sur les différentes optimisations génériques disponibles dans GCC on pourra utiliser avec profit la commande "gcc -Q --help=optimizers -O1". Cette commande, introduite dans la version 4.3, permet ici de lister toutes les passes d'optimisation de code qui sont activées au niveau -01. Dans le fichier pdf de présentation GCC de Laurent Guerby (voir cette dépêche LinuxFr) vous verrez qu'on peut s'amuser à compter ces optimisations de version en version.
Un "gcc -Q --help=optimizers -O1|wc -l" donne ainsi environ 140 lignes pour GCC 4.3, 160 pour la 4.4 et environ 180 pour la version 4.5.
Pour la suite (↑)
Le compte rendu complet du sommet annuel GCC 2009 permet d'avoir un aperçu du travail en cours sur le compilateur libre et de s'informer à l'avance sur les nouveautés qui arriveront dans les futures versions. Les articles (très techniques) au format PDF sont disponibles à cette adresse.
On y trouve notamment l'utilisation d'un outil graphique spécifique qui permet de faciliter l'écriture des greffons pour GCC (The visual development of GCC Plug-ins with GDE) ainsi que plusieurs articles sur les diverses stratégies d'optimisations du code (Optimization opportunities based on the polyhedral model in GRAPHITE et Interprocedural optimizations of function parameters).
Enfin, comme dans le compte-rendu de l'an dernier, on relève un article (Automatic Streamization in GCC) sur la très intéressante stratégie de "streamisation" qui consiste à optimiser un programme séquentiel pour qu'il s'exécute efficacement sur un processeur multicœurs...une technique d'avenir !
Aller plus loin
- Les nouveautés de GCC 4.5 (34 clics)
- Optimisation de l'édition des liens (5 clics)
- Les greffons de GCC (10 clics)
- Le greffon MELT (6 clics)
- DLFP: Sortie de GCC 4.4 (30 clics)
# Merci
Posté par Hojo . Évalué à -7.
Merci pour cette excellente dépêche.
[^] # Re: Merci
Posté par Anonyme . Évalué à -10.
Ceci dit je ne peux pas m'empêcher de commencer à trouver ces dépêches trop longues et trop détaillées.
A être moins synthétiques, elles perdent aussi de leur intérêt : tout le monde n'a pas le temps ni l'envie de s'investir dans moult détails, on ne retient pas l'essentiel.
Et de toutes manières ceux qui veulent creuser ne se contenteront jamais d'une telle dépêche.
Donc quel intérêt ?
[^] # Re: Merci
Posté par chtitux (site web personnel) . Évalué à 10.
Et comment occupe-t-on le vendredi ?
Pour l'intérêt et l'essentiel, il reste la 1ère partie de la dépêche pour les daicideurs pressés.
Une dépêche de 40 000 signes ne peut mériter qu'admiration envers son auteur.
[^] # Re: Merci
Posté par jujubickoille . Évalué à 1.
Merci encore Patrick_g !
[^] # Re: Merci
Posté par Guillaume Denry (site web personnel) . Évalué à 10.
[^] # Re: Merci
Posté par téthis . Évalué à 9.
Pour détourner une fausse citation célèbre : « 140 caractères sera suffisant pour tout le monde. ».
The capacity of the human mind for swallowing nonsense and spewing it forth in violent and repressive action has never yet been plumbed. -- Robert A. Heinlein
[^] # Re: Merci
Posté par Christophe Merlet (site web personnel) . Évalué à 6.
[^] # Re: Merci
Posté par Spack . Évalué à 1.
Derrière patrick_g se cachent sûrement plusieurs groupes de journalistes très spécialisés. Car avoir le temps de comprendre et en plus d'écrire un article pertinent puis y ajouter des liens (tombés d'on ne sait où) et des interviews non moins pertinents, à part s'appeler Google, je ne vois pas d'autres solutions.
Ce journal ( https://linuxfr.org/~patrick_g/29468.html ) n'était peut être pas une blague. Nous sommes en face d'un "robot-journaliste".
Sérieusement ! Quel est le secret ? Passer jours et nuits sur Internet sans dormir ? Avoir le cerveau relié en haut débit ? Je ne vois pas...
En tout cas bravo et merci !
[^] # Re: Merci
Posté par NickNolte . Évalué à 3.
Et en plus avec un éditeur de texte en ligne tout pourri!
Cela force l'admiration!
[^] # Re: Merci
Posté par rpnpif . Évalué à 2.
Très bon travail.
Merci Patrick.
[^] # Re: Merci
Posté par Hojo . Évalué à -5.
# Je vous demande de vous arrêter
Posté par goom . Évalué à 9.
J'ai l'immense regret de vous demander par ce commentaire ci-joint l'arrêt complet de vos contributions au site Linuxfr.org
En effet, non content de nous informer régulièrement de la sortie d'une nouvelle version du noyau Linux sur GNU, avec moults détails à faire passer n'importe quelle note de sortie du dernier logiciel à la mode de MS pour une comptine enfantine, voilà que vous comptez informer les lecteurs de ce magnifique site, une belle écloserie à troll, de la sortie de GCC dans sa version 4.5 (soit 9 x 0.5 si mes calculs sont exacts). Vous avez en plus l'outrecuidance d'écrire à propos de ce logiciel, pâle copie des plus brillants compilateurs propriétaires, là n'est pas le débat de toute façon, un article complet agrémenté de nombreux liens pour éclairer le lecteur au lieu de la conserver dans l'ignorance, et une court entretien avec un contributeur de GCC dont les réponses n'ont rien à envier à la longueur de vos écrits !!! C'est honteux de laisser s'exprimer ainsi un contributeur sur une telle longueur, tant d'octets perdus pour du blabla, c'est toute la productivité de la France, oui môssieur, de la France, qui en prend un coup et pire que tout, les lecteurs qui après avoir pris connaissance de cette information auront le sentiment d'être moins bête ! Mais où va-t-on si on rend n'importe qui plus intelligent à chaque nouvelle ? C'est la fin de tout !!
Ainsi, monsieur _g, Patrick, j'en appelle à votre sens civique, et je vous demande sur le champ de cesser vos contributions à ce site. (surtout que vous allez encore être gratifié en fin de mois pour vos contributions, si vous continuez comme ça il ne restera plus pour vous que l'abonnement à télé Z pendant un an !)
# goto ?
Posté par HardShooter . Évalué à 4.
On m'a dit pendant mes études que faire des goto c'était déjà une mauvaise habitude, on m'aurait menti ?
(je sais qu'il y en a pas mal dans le noyau linux mais j'aimerais savoir le vrai du faux)
[^] # Re: goto ?
Posté par Pierre Jarillon (site web personnel) . Évalué à 10.
J'ai réalisé en C un programme de navigation dans des menus qui utilisait des goto, c'était mieux que 10 niveaux d'indentation. Il est très facile à relire des années plus tard.
À l'opposé, mon premier programme (Fortran 4 sur cartes perforées) comporte tellement de goto que je n'arrive plus à le comprendre.
Le goto, c'est comme la langue d'Ésope, il peut être la meilleure ou la pire des choses, tout dépend de la façon dont il est employé.
[^] # Re: goto ?
Posté par HardShooter . Évalué à 10.
C'est bon à savoir, pendant mon DUT on m'a dit que c'était absolument à bannir (bon on m'a aussi dit que visual studio était meilleur que vim car il était payant...véridique)
[^] # Re: goto ?
Posté par claudex . Évalué à 10.
Il suffisait de leur vendre vim. En plus ça t'aurais fait de l'argent de poche.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: goto ?
Posté par Littleboy . Évalué à 4.
http://www.viemu.com/
[^] # Re: goto ?
Posté par GeneralZod . Évalué à 8.
C'est un raccourci pour éviter que les étudiants se mettent à pondre du code spaghetti.
On peut très bien se passer de goto en programmation structuré, mais goto permet d'alléger le code dans certains cas (gestion des exceptions, boucles imbriqués, regrouper les points de sorties d'une fonction). Bref, il y a plusieurs cas de figure ou goto est légitime (le code de Linux ou PulseAudio sont des exemples d'utilisation pertinente de goto).
Dans les langages plus haut niveau comme C++, Java et Python, on utilise à la place les exceptions.
[^] # Re: goto ?
Posté par lasher . Évalué à 6.
if (pulseaudio.enabled()) goto CATASTROPHE;
[^] # Re: goto ?
Posté par zerkman (site web personnel) . Évalué à 7.
Ca fait des années que je n'ai pas programmé en java, mais je ne sais plus quelle version de compilateur mettait comme message, en cas d'utilisation de goto : "goto not allowed", au lieu de mettre une bête erreur de syntaxe. On pouvait même placer des labels, ça ne posait aucun problème :) En gros, le goto a été implémenté pour des besoins internes compréhensibles, mais par contre il a été désactivé pour l'utilisateur. C'est pratique pour implémenter des langages, mais il ne faut pas le mettre entre toutes les mains. L'absurdité dans toute sa splendeur.
[^] # Re: goto ?
Posté par barmic . Évalué à 5.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Commentaire supprimé
Posté par Anonyme . Évalué à 2.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: goto ?
Posté par barmic . Évalué à 5.
D'une manière générale pouvoir argumenter les choix effectué dans son code est, il me semble, une excellente pratique.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: goto ?
Posté par Gniarf . Évalué à 1.
[^] # Re: goto ?
Posté par gaaaaaAab . Évalué à 4.
Je considère, comme Michel, qu'il faut pouvoir justifier chaque choix technique dans le code, en descendant au niveau de détail de la ligne de code. Le problème, c'est que quand un code est bien écrit, il peut y avoir plusieurs justifications (se renforçant mutuellement) pour certaines lignes de code.
SI je devais documenter absolument tous les éléments que je prends en compte quand je code, ben je coderais pas beaucoup :D
D'après moi, ce qu'il faut documenter dans le code, c'est plutôt l'intention qui le guide.
[^] # Re: goto ?
Posté par barmic . Évalué à 3.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: goto ?
Posté par barmic . Évalué à 5.
La différence c'est qu'ils ont plus de sémantiques que le goto et qu'il permettent plus de sécurité.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: goto ?
Posté par Perthmâd (site web personnel) . Évalué à 4.
Fortement typable, sûr, efficace (ou pas).
Incompréhensible pour le profane.
Que demande le peuple ?
[^] # Re: goto ?
Posté par auve . Évalué à 6.
GOTO c'est pour les enfants, les vrais hommes utilisent COMEFROM !
[^] # Re: goto ?
Posté par 2PetitsVerres . Évalué à 4.
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
[^] # Re: goto ?
Posté par psychoslave__ (site web personnel) . Évalué à 2.
[^] # Re: goto ?
Posté par gaaaaaAab . Évalué à 5.
Concernant le style de code, il n'y a pas de règle absolue, ça dépend vraiment du contexte. Je vise toujours la meilleure lisibilité possible quand je code, et en fonction du contexte, ça passe parfois par une variable de statut renvoyée en fin de fonction (comme tu le dis) et parfois par des retours en erreur au fil de la fonction.
Je précise aussi que je fais principalement de la maintenance de code, et que dans ce contexte là, on ne peut pas toujours se permettre de ré écrire tout tout beau tout propre.
[^] # Re: goto ?
Posté par kowalsky . Évalué à 4.
ça permet aussi ce genre de pratique de ne pas avoir de fonction qui arrive à la fin sans rencontrer de return (autre que celui mis par l'étudiant pour que le compilo soit content).
ça facilite aussi la complétion avec les outils comme NeBeans.
Mais en pratique, des petites entorses simplifieront le code et l'algorithme :)
[^] # Re: goto ?
Posté par defmonkey . Évalué à 2.
[^] # Re: goto ?
Posté par lasher . Évalué à 2.
Tu généralises, mais cette généralisation est fausse. J'avais des profs anti-goto, qui tout simplement ne nous ont jamais dit que ça existait, sauf une fois en cours, en nous expliquant que dans 90% des projets, ce serait inutile (et que dans les projets qu'ils nous donneraient, ça vaudrait des points en moins). Oui, ils disaient en gros « le goto, c'est mal ». Et ils ont raison. Il y a des cas particuliers où c'est justifié, mais presque jamais. Pour le break, c'était autorisé à condition d'avoir une utilité réelle (i.e. : qu'on ne puisse pas changer la structure de l'algo d'abord, et si c'est réellement le mieux auquel on puisse penser, alors bon, pourquoi pas).
De plus, je ne vois pas ce que switch vient faire là-dedans. Un switch-case n'a rien à voir avec goto/break, sauf à vouloir faire des trucs moches genre duff's device.
« Ca fait des années que je n'ai pas programmé en java, mais je ne sais plus quelle version de compilateur mettait comme message, en cas d'utilisation de goto : "goto not allowed" »
Ce n'est pas une erreur de syntaxe à mon sens. Le mot-clef "goto" est bien réservé en Java, pour en interdire l'utilisation. :)
[^] # Re: goto ?
Posté par Kerro . Évalué à 2.
Les goto c'est rare, mais ça sauve parfois la situation. Sinon, comme expliqué plus haut, on a des niveaux d'indentation hyper moches.
[^] # Re: goto ?
Posté par HardShooter . Évalué à 2.
[^] # Re: goto ?
Posté par lasher . Évalué à 5.
Maintenant, d'un point de vue compilation, le goto est extrêmement dangereux dans 90% des cas:
1/ Un goto qui revient en arrière, ça revient à faire une boucle, sans que le compilateur puisse facilement le deviner (enfin, si, mais non).
2/ Un goto qui sort d'une structure de contrôle, c'est mal -- surtout si c'est une boucle. Ça empêche le compilateur de générer un code optimisé. Évidemment, s'il s'agit d'un truc du genre if (catastrope_détectée) goto CATASTROPHE; c'est différent, vu que ça revient à implémenter des exceptions... Mais dans tous les cas, c'est à réserver pour des utilisations « uniques ».
3/ Un goto qui arrive en plein milieu d'une boucle, c'est criminel. Il faut pendre haut et court le mec qui fait ça.
[^] # Re: goto ?
Posté par brendel . Évalué à 3.
[^] # Re: goto ?
Posté par lasher . Évalué à 3.
[^] # Re: goto ?
Posté par defmonkey . Évalué à 6.
Oui. Personnellement, je l'utilise pour factoriser la gestion des erreurs. Ça évite la duplication de code. D'ailleurs, c'est souvent fait comme ça dans le noyau Linux, et Linus le revendique, cf http://kerneltrap.org/node/553/2131
[^] # Re: goto ?
Posté par guppy . Évalué à 4.
(je sais qu'il y en a pas mal dans le noyau linux mais j'aimerais savoir le vrai du faux)
C'est effectivement une mauvaise habitude : il faut tenter de s'en passer. Mais il y a certains cas (rares) qui gagnent (un peu) en terme de lisibilité à être écrit avec un goto.
Pour moi, les attitudes dogmatiques ne sont pas les bienvenues dans le développement : le développeur doit savoir pourquoi il n'utilise pas telle ou telle possibilité du langage ; il ne doit pas en refuser l'utilisation parce qu'on lui a dit. Le développement n'est pas une foi, mais une science. Les étudiants sont un cas un peu à part, je pense qu'il est parfois bénéfique pour eux d'avoir quelques règles à ne pas enfreindre afin de pouvoir se concentrer sur d'autres aspects. Mais une fois devenu professionnel, il faut y revenir !
[^] # Re: goto ?
Posté par gnumdk (site web personnel) . Évalué à 2.
Après, c'était peut être vrai pour des compilateurs dans les années 70 mais quid aujourd'hui ?
[^] # Re: goto ?
Posté par lasher . Évalué à 1.
[^] # Re: goto ?
Posté par fedorat . Évalué à 5.
Le développement, et particulièrement le codage, sont un art!
[^] # Re: goto ?
Posté par psychoslave__ (site web personnel) . Évalué à 1.
[^] # Re: goto ?
Posté par gaaaaaAab . Évalué à 4.
[^] # Re: goto ?
Posté par gaaaaaAab . Évalué à 2.
s/de vous/de toi/ ...
[^] # Re: goto ?
Posté par psychoslave__ (site web personnel) . Évalué à 2.
[^] # Re: goto ?
Posté par El Titi . Évalué à 2.
[^] # Re: goto ?
Posté par Joël Thieffry (site web personnel) . Évalué à 4.
[^] # Re: goto ?
Posté par claudex . Évalué à 10.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: goto ?
Posté par El Titi . Évalué à 1.
[^] # Re: goto ?
Posté par cedric . Évalué à 4.
[^] # Re: goto ?
Posté par Ummon . Évalué à 3.
void fun()
{
// [code]
goto error;
// [code]
goto error;
// etc..
if (0) // catch déguisé
{
error:
// traitement de l'erreur
}
}
(la balise 'code' m'a viré l'indentation, pas très malin)
[^] # Re: goto ?
Posté par Mildred (site web personnel) . Évalué à 3.
[^] # Re: goto ?
Posté par Ummon . Évalué à 2.
[^] # Re: goto ?
Posté par liberforce (site web personnel) . Évalué à 4.
if (do_step_1 () == FALSE)
goto err_step_1;
if (do_step_2 () == FALSE)
goto err_step_2;
if (do_step_3 () == FALSE)
goto err_step_3;
return TRUE;
err_step_3 :
undo_step_3 ();
err_step_2 :
undo_step_2 ();
err_step_1 :
undo_step_1 ();
return FALSE;
[^] # Re: goto ?
Posté par M . Évalué à 2.
int ret = 0;
enum {
DING_OK,
DING_ERR1,
DING_ERR2,
} ding = DING_OK;
if (ding == DING_OK) {
if (do_step_1 () == FALSE) {
ding = DING_ERR1;
ret = 1;
}
}
if (ding == DING_OK) {
if (do_step_2 () == FALSE) {
ding = DING_ERR2;
ret = 2;
}
}
switch(ding) {
case DING_ERR2:
undo_step_2 ();
case DING_ERR1:
undo_step_1();
case DING_OK:
}
return ret;
PS : ding is not a goto
[^] # Re: goto ?
Posté par liberforce (site web personnel) . Évalué à 2.
[^] # Re: goto ?
Posté par Croconux . Évalué à 3.
Sans exagérer ça donnerait plutôt ça :
if (do_step_1 () == FALSE)
{
undo_step_1 ();
return FALSE;
}
if (do_step_2 () == FALSE)
{
undo_step_2 ();
return FALSE;
}
if (do_step_3 () == FALSE)
{
undo_step_3 ();
return FALSE;
}
return TRUE;
C'est tellement plus compliqué ?
[^] # Re: goto ?
Posté par Ummon . Évalué à 5.
[^] # Re: goto ?
Posté par cedric . Évalué à 3.
[^] # Re: goto ?
Posté par gaaaaaAab . Évalué à 3.
Je suis justement en train de relire code complete [1], et ce qu'on peut reprocher à la fonction en exemple, c'est d'avoir une homogénéité séquentielle, ce qui n'est pas l'idéal.
Forcément, sur cet exemple "creux", on ira pas très loin, mais sur un exemple plus concret, il y aurait surement des moyens de réorganiser le code à plus haut niveau pour qu'on ne se retrouve pas dans cette situation.
[1] http://www.amazon.fr/Code-Complete-Steven-C-McConnell/dp/073(...)
Il y a aussi une VF. Quand je vois comment ce bouquin m'a fait progresser, je ne peux que vivement vous encouragez à le lire si ce n'est pas déjà fait.
[^] # Re: goto ?
Posté par IsNotGood . Évalué à 2.
En pseudo code
tab = { {do_step_1, undo_step_1}, {do_step_2, undo_step_2} ... } ;
for (i=0 ; i < sizeof(tab) ; i++) {
if (!tab[i][0]) {
do { tab[i][1] ; } while (i--) ;
return FALSE
}
}
return TRUE
Je n'ai pas codé en C depuis des lustres :-)
[^] # Re: goto ?
Posté par IsNotGood . Évalué à 2.
f() {
tab = { {do_step_1, undo_step_1}, {do_step_2, undo_step_2} ... } ;
return g (tab, tab+sizeof(tab)) ;
}
g (p_tab, p_tab_end) {
if (p_tab < p_tab_end) {
if (!p_tab[0]) { p_tab[1] ; return FALSE ; } }
else { return TRUE }
return g(++p_tab, p_tab_end)) ;
}
[^] # Re: goto ?
Posté par IsNotGood . Évalué à 2.
f() {
tab = { {do_step_1, undo_step_1}, {do_step_2, undo_step_2} ... } ;
return g (tab, tab+sizeof(tab)) ;
}
g (p_tab, p_tab_end) {
if (p_tab < p_tab_end) {
if (!p_tab[0]) { p_tab[1] ; return FALSE ; } }
else { return TRUE }
if (!g(++p_tab, p_tab_end))) {
p_tab[1] ; return FALSE ; }
return TRUE ;
}
[^] # Re: goto ?
Posté par psychoslave__ (site web personnel) . Évalué à 3.
bool make_steps_until( int step_to_reach ){
bool all_steps_done = true;
for( int step = 0; step < step_to_reach; step++ ){
if( do_step( step ) == false ) {
undo_from_step( step );
all_steps_done = false;
}
}
return all_steps_done;
}
On peut aussi imaginer renvoyer la dernière étape effectuée (avec succès, ou non), ce qui permet de faire un traitement plus précis du retour.
Je suis intéressé par les critiques. :)
[^] # Re: goto ?
Posté par psychoslave__ (site web personnel) . Évalué à 0.
int ma_fonction() {
int res = LA_CONSTANTE_G_RIEN_FOUTU ;
[…] // tout un tas de trucs qui modifie éventuellement res.
return res ;
}
# Déjà dans Debian !
Posté par barmic . Évalué à 2.
Je vais faire chauffer mon apt-build :)
J'aurais tout de même une question :
Il es fait mention de code des aspects en greffons, est-il possible de voir apparaitre un tisseur sous forme de greffon ?
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
# Pourquoi ?
Posté par Zarmakuizz (site web personnel) . Évalué à -6.
Euh, pourquoi, notre patrick_g serait-il corrompu ?
Commentaire sous licence LPRAB - http://sam.zoy.org/lprab/
# LD - Linkage
Posté par phoenix (site web personnel) . Évalué à 3.
Pour commencer : très bonne dépêche.
Sinon j'avais une petite question à propos de LD. J'ai découvert, il y a peu GOLD qui permet d'accélerer le temps de linkage.
Est-ce que GCC va inclure GOLD un jour ? Pourquoi ne pas l'utiliser en standard ? Est-ce qu'il marche toujours avec GCC 4.5 ?
Merci
[^] # Re: LD - Linkage
Posté par patrick_g (site web personnel) . Évalué à 4.
Aucune idée.
>>> Est-ce qu'il marche toujours avec GCC 4.5 ?
Oui puisqu'il est mentionné sur la page LTO que j'ai donné en lien :
"As an added feature, LTO will take advantage of the plugin feature in gold. This allows the compiler to pick up object files that may have been stored in library archives. To use this feature, you must be using gold as the linker and enable the use of the plugin by compiling with gcc -fuse-linker-plugin. This will shift the responsibility of driving the final stages of compilation from collect2 to gold via the linker plugin".
http://gcc.gnu.org/wiki/LinkTimeOptimization#Requirements
[^] # Re: LD - Linkage
Posté par GeneralZod . Évalué à 5.
> il y a peu GOLD qui permet d'accélérer le temps de linkage.
GOLD est encore jeune et pas tout à fait au même niveau que le bon vieux GNU ld. GOLD est parfois plus lent (voire significativement plus lent pour certains logiciels) et le binaire résultant est rarement plus petit. De plus GOLD ne supporte qu'ELF et se limite à la plateforme x86.
http://lists.fedoraproject.org/pipermail/devel/2010-March/13(...)
L'intérêt de GOLD est d'avoir un linker plus facilement maintenable à l'avenir et d'améliorer le support du C++. En pratique, GOLD est très rapide à linker du C++, même si les benchs ci-dessus semble démontrer le contraire (je pense qu'il a juste du mal avec des logiciels aussi complexe que ceux de la MoFo)
[^] # Re: LD - Linkage
Posté par lasher . Évalué à 2.
Parfois plus lent peut-être, mais en pratique, je connais des collègues autour qui n'ont pu effectuer l'édition de lien de leur que grâce à GOLD (ld finissait en out-of-memory).
[^] # Re: LD - Linkage
Posté par phoenix (site web personnel) . Évalué à 1.
[^] # Re: LD - Linkage
Posté par GeneralZod . Évalué à 3.
> mais en pratique, je connais des collègues autour qui n'ont pu effectuer l'édition de lien de leur que grâce à GOLD (ld finissait en out-of-memory).
question qui me turlupine, ils faisaient comment avant ?
[^] # Re: LD - Linkage
Posté par lasher . Évalué à 3.
Il (le collègue) faisait pas. :)
Ça s'est passé un peu comme ça :
Collègue: Rah, ça compile mais à l'édition de lien ça me plante !
Moi: T'as essayé GOLD ?
Collègue: Gné ?
[s'en suit une courte explication, et une tentative du collègue avec GOLD]
Collègue: Ça marche !
[^] # Re: LD - Linkage
Posté par GeneralZod . Évalué à 2.
# GCCGO
Posté par Yakulu . Évalué à 4.
Une petite question : en janvier dernier, il avait été annoncé sur la liste gcc-dev [http://thread.gmane.org/gmane.comp.gcc.devel/111603/focus=11(...)] que GCCGO, l'un des deux compilateurs du langage de programmation de Google, serait inclus dans GCC 4.5 or later.
Visiblement, il n'a pas été intégré dans la 4.5, avez-vous des nouvelles à ce propos ? Je ne suis pas bien au courant de la manière dont cela se passe mais l'acceptation du comité GCC signifie-t-il que GCCGO fera partie du compilateur standard, au même titre que g++, GNAT... ?
Merci d'avance.
[^] # Re: GCCGO
Posté par patrick_g (site web personnel) . Évalué à 3.
Cela se fera sans doute pour la version 4.6...rendez-vous pour la news d'avril 2011 donc !
# LinkTimeOptimisation
Posté par Guillaum (site web personnel) . Évalué à 4.
J'ai souvent tendance à écrire du code à grand coup d'inline dans les .h, par exemple dans le cas d'une libraire de gestion de vecteur, le .h contenant la definition de struct et toutes les méthodes en static inline. Evidament la compilation prend beaucoup de temps car si je modifie une unique ligne de code dans un .h inclue dans TOUT le projet, il faut recompiler tous les .o du projet et refaire le link.
Grace au link time optimisation, je devrais pouvoir simplement declarer mon interface de vector dans mon .h, mettre le code dans un .c, compiler mes .o et lors du link, il doit pouvoir inliner après coup non ? Donc je perd un petit peu en temps de link, mais j'y gagne surement en temps de compilation.
Et je vais meme etre plus bourin. Actuellement je declare toutes mes petites fonctions en static inline, mais finalement pourquoi ne pas laisser gcc faire correctement son travail et n'inliner que ce qui vaut vraiment le coup ? (Et en théorie il le sait mieux que moi ?)
Donc, la "bottom-line" devient plutot: verra-t-on dans les mois à venir la disparition des interface .h fourre-tout static inline au profit d'un code bien separé .h/.o et mieux optimisé ?
Autre question, GCC sera il capable d'eliminer (et informer) à propos de la présence de code mort/ fonction non appelée ?
[^] # Re: LinkTimeOptimisation
Posté par Guillaum (site web personnel) . Évalué à 3.
Et autre question, quand on a 2000 .o qui instancient le meme template, comment GCC faisait-t-il avant, il dupliquait le code entre chaque .o et la duplication restait après le link ? (Mon dieu !)
[^] # Re: LinkTimeOptimisation
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Pour ton problème, il faut utiliser la précompilation de header. En gros, avec Gcc depuis un moment, tu peux compiler un header comme un .c. Je crois que tu ne peux le faire que pour un seul header, par contre.
"La première sécurité est la liberté"
[^] # Re: LinkTimeOptimisation
Posté par Troy McClure (site web personnel) . Évalué à 3.
quand on a 2000 .o qui instancient le meme template, comment GCC faisait-t-il avant, il dupliquait le code entre chaque .o et la duplication restait après le link ?
ils sont dupliqués dans les .o , en tant que symboles faibles. Le link regroupe les symboles faibles de même nom et au lieu de generer une erreur du genre "le symbole toto est defini dans plusieurs fichiers" il n'en garde qu'un (choisi au hasard , mais si tu n'as pas changé tes flags de compilation en plein milieu du build ils sont identiques). D'autre part si tu compiles tes sources avec -ffunction-sections et que tu linkes avec -Wl,--gc-sections le linker eliminera les fonctions non utilisées
[^] # Re: LinkTimeOptimisation
Posté par Guillaum (site web personnel) . Évalué à 1.
En pratique cela veut donc dire que GCC fait la compilation et l'instanciation des templates pour chaque .o alors qu'il pourrait le faire seulement au link, donc un gain de temps qui pourrait étre sympa.
[^] # Re: LinkTimeOptimisation
Posté par GeneralZod . Évalué à 2.
Tu peux forcer l'instanciation d'une spécialisation d'un template par simple déclaration:
template class Truc;
C'est déjà prévu dans la norme, notamment pour faciliter la vie des bibliothèques réutilisables.
[^] # Re: LinkTimeOptimisation
Posté par defmonkey . Évalué à 1.
À l'époque où j'avais essayé le langage Eiffel, le compilateur du Loria ne permettait pas ce mécanisme dynamique et pouvait donc facilement déceler du code mort et faire de l'optimisation globale. Mais ici ...
[^] # Re: LinkTimeOptimisation
Posté par Guillaum (site web personnel) . Évalué à 1.
[^] # Re: LinkTimeOptimisation
Posté par ecyrbe . Évalué à 1.
pour l'utiliser via gcc : -Wl,-whole-archive. et -Wl,-no-whole-archive
[^] # Re: LinkTimeOptimisation
Posté par GeneralZod . Évalué à 4.
Ce serait une bonne idée, inliner n'est pas systématiquement une optimisation, la plupart du temps, c'est pire encore (vu qu'on génère plus de cache miss).
La plupart des compilateurs savent parfaitement gérer les cas triviaux (opérations atomiques) et les cas plus complexes, mieux que le développeur. De toute façon, le mot clé inline en C et C++ n'est qu'une indication pour le compilateur et non pas une règle absolue.
En général, on ne devrait inliner les fonctions qu'après profilage.
> Autre question, GCC sera il capable d'eliminer (et informer) à propos de la présence de code mort/ fonction non appelée ?
Une des applications possibles des greffons dans GCC est de permettre l'intégration d'analyseur syntaxique comme le fait LLVM/Clang (que tu devrais essayer, ne serait-ce que pour cette fonctionnalité)
[^] # Re: LinkTimeOptimisation
Posté par barmic . Évalué à 2.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
# et mon canal carpien alors?
Posté par ZeroHeure . Évalué à 1.
on est obligé de faire défiler longtemps longtemps longtemps toute la page jusqu'en haut pour cliquer sur pertinent.
Je suggère d'ajouter les liens pour "pertinenter" au bas de la deuxième partie de la dépêche.
"La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay
# Y a une faute !
Posté par Christophe Duparquet (site web personnel) . Évalué à 1.
« J'ai pas Word, j'ai pas Windows, et j'ai pas la télé ! »
# Dépêche incomplète !
Posté par Victor STINNER (site web personnel) . Évalué à 2.
GCC 4.5 features improved experimental support for the upcoming ISO C++ standard, C++0x, including support for raw strings, lambda expressions and explicit type conversion operators. An experimental profile mode has also been added to the libstdc++ runtime library. Other improvements have been made to the optimiser and integration with the MPC library allows GCC to more accurately evaluate complex arithmetic during optimisation. The developers also note that GCC now requires the MPC library in order to build.
New target platforms include among others the ARM Cortex-M0 and Cortex-A5 processors and the ARM v7E-M architecture and MIPS 1004K processors. Support for a number of older platforms, such as Tru64 Unix, Irix and Solaris 7, has been discontinued.
http://www.h-online.com/open/news/item/GNU-Compiler-Collecti(...)
[^] # Re: Dépêche incomplète !
Posté par patrick_g (site web personnel) . Évalué à 2.
Certes je n'ai pas détaillé la liste des nouveautés de C++0x mais il y a quand même un paragraphe dessus pour ceux qui veulent aller voir de plus près (le treizième des nouveautés en bref).
[^] # Re: Dépêche incomplète !
Posté par Guillaum (site web personnel) . Évalué à 1.
(On est vendredi hein ;)(J'aime pas le C++)(Je bosse avec tous les jours)(Comme George Abitbol aurait dis, monde de
[^] # Re: Dépêche incomplète !
Posté par Victor STINNER (site web personnel) . Évalué à 5.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.