URL: https://linuxfr.org/news/sortie-de-la-version-4-7-du-compilateur-gcc Title: Sortie de la version 4.7 du compilateur GCC Authors: patrick_g baud123, Benoît Sibaud, Nils Ratusznik, claudex, NeoX, j et rootix Date: 2012年03月20日T21:59:12+01:00 License: CC By-SA Tags: richard_stallman, objective-c, linus_torvalds, fortran, firefox, lwn et gcc Score: 84 La nouvelle version majeure du [compilateur GCC](http://gcc.gnu.org/) du projet [GNU](http://fr.wikipedia.org/wiki/Projet_GNU) vient de sortir ([voir l'annonce](http://gcc.gnu.org/ml/gcc-announce/2012/msg00002.html)). Écrit à l'origine par [Richard Stallman](http://fr.wikipedia.org/wiki/Richard_Stallman), le logiciel GCC (GNU Compiler Collection) est le compilateur de référence du monde du logiciel libre. [Il accepte](http://gcc.gnu.org/frontends.html) des codes source écrits en C, C++, Objective-C, Fortran, Java, Ada, Go et il fonctionne sur [une multitude d'architectures](http://en.wikipedia.org/wiki/GNU_Compiler_Collection#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.7 de GCC, ainsi qu'un entretien avec Torvald Riegel, qui a développé avec Richard Henderson et Aldy Hernandez le code gérant la [mémoire transactionnelle](http://fr.wikipedia.org/wiki/M%C3%A9moire_transactionnelle_logicielle). ---- [Les nouveautés de GCC 4.7](http://gcc.gnu.org/gcc-4.7/changes.html) [La mémoire transactionnelle dans GCC](http://gcc.gnu.org/wiki/TransactionalMemory) [LinuxFr : Sortie de GCC.4.6](http://linuxfr.org/news/la-version-46-du-compilateur-gcc-est-disponible) [Page d'accueil du projet](http://gcc.gnu.org/) ---- #Prise en charge de la mémoire transactionnelle Le compilateur GCC en version 4.7 propose, pour la première fois, une gestion de la technique dite de « [mémoire transactionnelle](http://fr.wikipedia.org/wiki/M%C3%A9moire_transactionnelle_logicielle) » (TM pour **T**ransactional **M**emory). Cette prise en charge est considérée comme expérimentale à l'heure actuelle mais elle est amenée à s'étoffer dans les versions futures. Pour créer un programme capable d'exploiter simultanément plusieurs processeurs, il est nécessaire de mettre en place un mécanisme empêchant les divers cœurs de calcul d'effectuer des actions contradictoires au même moment ou d'accéder aux mêmes ressources simultanément. Le modèle traditionnel de [programmation concurrente](http://fr.wikipedia.org/wiki/Programmation_concurrente) est celui qui utilise des [verrous](http://fr.wikipedia.org/wiki/Verrou_%28informatique%29), pour interdire ces accès simultanés aux ressources partagées. Le programme va simplement poser un verrou sur une ressource bien précise, afin de pouvoir travailler avec elle sans risquer une interférence de la part des autres processeurs. Les verrous (_locks_) constituent donc une solution acceptable mais, hélas, ce paradigme n'est pas sans défauts. On peut opter pour un verrou simple qui protège une grande partie du système, mais dans ce cas les performances sont faibles puisque les autres processeurs restent souvent en attente. On peut également implémenter une multitude de petits verrous ne protégeant que des zones limitées. Les performances s'améliorent mais la complexité du code devient dangereuse et le risque de bug est élevé ([interblocages](http://fr.wikipedia.org/wiki/Interblocage), [inversions de priorité](http://fr.wikipedia.org/wiki/Inversion_de_priorit%C3%A9), etc). Au lieu de créer ainsi des verrous de plus en plus fins, peut-être faudrait-il reconsidérer le problème et partir sur une solution complètement différente ? Le mécanisme de « mémoire transactionnelle » a l'ambition d'être cette solution alternative, permettant d'exploiter les machines multiprocesseurs, sans avoir à utiliser le très complexe verrouillage à grains fins. Pour comprendre en quoi consiste cette fameuse mémoire transactionnelle, il faut tout d'abord prendre conscience qu'il s'agit là d'une technique optimiste. Dans le cas des verrous, on protège les ressources partagées parce qu'on craint une modification simultanée de la part d'un autre processeur. On est pessimiste puisqu'on pense qu'un concurrent va, lui aussi, faire des changements au même moment. Le verrou n'est donc posé que pour être _certain_ que tout va bien se passer dans tous les cas. Avec la mémoire transactionnelle, on est optimiste et on parie sur la fait que tout va bien se passer _sans_ avoir besoin de verrouiller l'accès. En effet, dans la plupart des cas, la compétition pour l'accès à une ressource n'est pas si féroce que ça. Un seul cœur de calcul pourra faire son travail sans que les autres n'essayent à tout prix d'effectuer d'autres changements sur la même ressource juste au même moment. Le mécanisme de mémoire transactionnelle tire parti de cet état de fait puisqu'il se contente de vérifier, **a posteriori**, que tout s'est bien passé lors d'un changement. Si c'est bien le cas, alors la vie est belle et on peut passer à autre chose. Si, au contraire, on s'aperçoit qu'un autre processeur a lui aussi fait des modifications sur la même ressource, alors on effectue un retour arrière pour annuler le changement. Techniquement, ce mode de fonctionnement se rapproche de celui d'une base de données, avec les notions de transaction atomique de commit en cas de succès et de rollback en cas d'échec. On distingue la mémoire transactionnelle matérielle (HTM) de la mémoire transactionnelle logicielle (STM). Dans le premier cas, il faut une prise en charge par le processeur, ce qui est encore très rare à l'heure actuelle. La puce [Rock](http://en.wikipedia.org/wiki/Rock_%28processor%29) a été annulée par Sun/Oracle mais les puces IBM du supercalculateur [BlueGene/Q](http://en.wikipedia.org/wiki/Bluegene#Design_2)) et surtout la prochaine génération de processeur Intel ([nom de code Haswell](http://software.intel.com/en-us/blogs/2012/02/07/transactional-synchronization-in-haswell/)) utilisent ce mécanisme de mémoire transactionnelle matérielle. Dans le second cas de la STM, on se contente d'émuler ce support via des routines logicielles (qui utilisent des instructions atomiques et mêmes des verrous). Bien entendu, on peut aussi utiliser une approche hybride, mêlant HTM et STM, pour avoir une sémantique plus riche et de meilleures performances. Les partisans de la technique de mémoire transactionnelle soulignent que ce paradigme simplifie grandement le travail du développeur. Ce dernier doit simplement indiquer dans son code, à l'aide du mot-clé `__transaction`, quels sont les blocs qui seront considérés comme « atomiques », c'est-à-dire les blocs qui devront s'exécuter au sein d'une transaction. Bien entendu, il faudra voir à l'usage quels seront les réels bénéfices de cette approche de la programmation via la mémoire transactionnelle. Est-ce que les gains de productivité promis seront au rendez-vous ? Est-ce qu'il y aura vraiment moins de bugs qu'avec les verrous classiques et si oui, quelle sera la déperdition en matière de performances ? Linus Torvalds [n'est pas très optimiste](http://www.realworldtech.com/forums/index.cfm?action=detail&id=127396&threadid=127314&roomid=2) (_every single time somebody has tried transactional memory, the failure costs swamp the advantages_) mais au moins, grâce à GCC 4.7, il est possible d'essayer ce nouveau paradigme. Dans GCC, la nouvelle fonction de mémoire transactionnelle s'active en passant la commande `-fgnu-tm` au compilateur. L'implémentation de ces fonctions se fait via la bibliothèque `libitm` et la prise en charge n'est assurée, dans les langages C et C++, que pour les architectures x86-64, x86-32 et Alpha. Le travail d'optimisation n'a pas encore été fait et les performances seront donc sans doute assez faibles mais [les développeurs insistent](http://gcc.gnu.org/wiki/TransactionalMemory) sur le fait que cette lenteur n'est pas inhérente à la technique de STM : > _Cette prise en charge est expérimentale. Cela signifie en particulier que plusieurs parties de l'implémentation TM ne sont pas encore optimisées. Si vous constatez un niveau de performance plus bas que ce qui est attendu, vous ne devriez pas en conclure que la mémoire transactionnelle est inéluctablement lente. Au contraire, profitez-en pour ouvrir un bug._ L'implémentation de la mémoire transactionnelle dans GCC 4.7 est le [résultat d'un financement](http://cordis.europa.eu/search/index.cfm?fuseaction=proj.document&PJ_RCN=9834137) de l'Union européenne (programme-cadre de recherche [FP7](http://cordis.europa.eu/fp7/understand_en.html)). [Le projet Velox s'est déroulé sur trois ans](http://www.velox-project.eu/), entre 2008 et 2010, et nous en voyons maintenant les résultats avec cette intégration du code écrit à cette occasion. En dehors de divers essais dans le monde académique et de versions expérimentales chez Intel, GCC 4.7 est le tout premier compilateur de production à proposer cette prise en charge de la mémoire transactionnelle. Pour aller plus loin dans la découverte de la fonction de mémoire transactionnelle dans GCC, j'ai posé quelques questions à [Torvald Riegel](http://www.velox-project.eu/people/dipl-inf-torvald-riegel), qui est maintenant un développeur Red Hat, mais qui a travaillé sur TM au sein du projet Velox. #Entretien avec Torvald Riegel **_LinuxFr : Pourquoi est-ce que GCC est le premier des grands compilateurs à proposer cette fonction de mémoire transactionnelle ? Est-ce vraiment difficile à implémenter ?_** **Torvald Riegel :** Il y a eu des implémentations de TM dans des versions prototypes d'autres compilateurs (ICC par exemple). TM n'est pas plus difficile à implémenter que les autres fonctions d'un compilateur. Je ne peux pas faire de commentaires à propos des roadmaps des autres compilateurs, mais nous voudrions que GCC offre un bon support et de bonnes abstractions de programmation pour le parallélisme et la concurrence. Des fonctionnalités comme la mémoire transactionnelle et le support du modèle mémoire de C++11 font partie de cet effort. ___ **_LinuxFr : Pourquoi avoir choisi GCC par rapport à LLVM ? Penses-tu que LLVM aura lui aussi bientôt une implémentation de TM ?_** **Torvald Riegel :** La gestion de TM dans GCC est le résultat du travail de plusieurs personnes de la communauté GCC, donc la question devrait plutôt être : pourquoi les communautés GCC et LLVM ont ou n'ont pas implémenté la mémoire transactionnelle jusqu'à présent ? Un travail sur la gestion de TM dans LLVM avait été entrepris il y a quelque temps, mais la communauté GCC a été bien plus réceptive et intéressée pour travailler sur ce sujet. ___ **_LinuxFr : Est-il réellement possible de rivaliser avec les verrous en termes de performances ou bien est-ce que TM est surtout un mécanisme de synchronisation alternatif, plus lent mais plus facile à utiliser ?_** **Torvald Riegel :** La réponse courte est oui. Pour la réponse longue, nous devons d'abord réaliser que les verrous, comme la mémoire transactionnelle, sont avant tout des _abstractions_ permettant la programmation. Il y a différentes sortes de verrous, avec des caractéristiques très différentes en termes de performances, et la même chose est vraie pour les implémentations TM (par exemple les différents algorithmes, les différentes approches hybrides logiciel/matériel, etc.). En plus de toute cette variété, les programmeurs utilisent ces abstractions de toute sorte de façons (par exemple le verrouillage à grains fins contre l'utilisation de gros verrous) et pour toutes sortes de tâches. En conséquence, on ne peut pas comparer de manière pertinente les verrous et la mémoire transactionnelle sans préciser d'autres paramètres. Si on ne le fait pas, alors on risque de simplifier outrageusement les choses. Il faut également prendre en compte le fait que le développement logiciel est souvent un processus en best effort, en particulier en ce qui concerne l'optimisation pour les performances. Si une abstraction est plus facile à utiliser (par exemple vous n'avez pas à vous préoccuper de l'ordre d'acquisition des verrous quand vous utilisez TM), alors cela peut permettre au programmeur de passer plus de temps sur l'optimisation (par exemple sur les transactions) et peut donc conduire à un programme plus rapide au final. Nous voulons effectivement que l'utilisation de la mémoire transactionnelle soit plus simple que la technique des verrous, mais je pense que, à temps de développement égal, TM peut avoir dans un grand nombre de situations des performances qui sont au moins aussi bonnes, si ce n'est meilleures qu'une implémentation à base de verrous. Toutefois, il faudra sans doute attendre quelques itérations des implémentations TM (qu'il s'agisse du hardware ou de la partie logicielle). La mémoire transactionnelle est encore une technologie nouvelle. Des techniques comme les ramasse-miettes ont, elles aussi, nécessité du temps avant de pouvoir exploiter tout leur potentiel. ___ **_LinuxFr : Est-ce qu'il est important qu'apparaissent des implémentations matérielles comme dans le futur Intel Haswell ?_** **Torvald Riegel :** La gestion par le matériel de la mémoire transactionnelle (HTM) permettra sans aucun doute d'atteindre plus facilement de bons niveaux de performances. Je suis vraiment impatient que les processeurs avec gestion HTM deviennent plus répandus. ___ **_LinuxFr : Que penses-tu de cette citation de Linus Torvalds: « Chaque fois que quelqu'un a essayé la mémoire transactionnelle, les désavantages l'ont emporté sur les avantages »._** **Torvald Riegel :** Cette phrase, que tu as citée seulement partiellement, débute par « [afaik](http://fr.wiktionary.org/wiki/AFAIK) ». Tu peux aussi remarquer que les échanges sur ce thread portent sur une implémentation matérielle spécifique (Haswell) et se concentrent sur la technique de « lock elision » (c'est-à-dire se servir de la gestion HTM et des possibilité d'exécutions spéculatives et de transactions pour optimiser l'exécution d'un code utilisant les verrous). En outre, il semble s'agir du noyau Linux ou d'autres types de codes très optimisés qui ont déjà une architecture sophistiquée basée sur les verrous. Les études pour d'autres implémentation HTM montrent des résultats différents pour d'autres types de code, même quand il s'agit d'implémentations HTM aussi limitées que celle du processeur Sun Rock (voir [l'article ASPLOS 2009](http://www.multicoreinfo.com/research/papers/2009/asplos09-RockHTM.pdf) pour les détails). Le but premier de la gestion de la mémoire transactionnelle dans GCC, c'est d'offrir aux développeurs normaux une abstraction de programmation basée sur les transactions. ___ **_LinuxFr : Est-ce que tu prévois d'améliorer l'implémentation TM dans les futures versions de GCC ? Il y a une roadmap quelque part ?_** **Torvald Riegel :** Oui, nous voulons continuer à travailler pour améliorer le support de la mémoire transactionnelle dans GCC (que ce soit au niveau du compilateur ou dans libtm, la bibliothèque de runtime TM de GCC). Par exemple l'amélioration des performances fait, bien entendu, partie de notre liste des choses à faire (ce qui comprend l'exploitation du support HTM). Il n'y a pas de roadmap définitive pour le moment, nous espérons plutôt un retour de la part des utilisateurs de façon à ce que nous puissions définir des priorités sur les aspects à améliorer en premier. Donc les commentaires des utilisateurs sont tout à fait bienvenus. ___ **_LinuxFr : Est-ce que tu peux dire un mot sur le projet Velox ? Est-ce qu'il a été important pour la création de cette implémentation de mémoire transactionnelle ?_** **Torvald Riegel :** Une part importante de l'implémentation TM dans GCC a été créée pendant le déroulement de ce projet Velox. Nous sommes impatients de continuer à collaborer avec des groupes de recherche. **_LinuxFr : Au nom de tous les lecteurs, merci pour tes réponses et pour ton travail dans GCC._** ___ #En bref ##Architecture x86-64 GCC 4.7 permet maintenant d’optimiser spécifiquement le code pour les nouvelles générations de processeurs x86. La version améliorée de l'architecture [Bulldozer](http://en.wikipedia.org/wiki/AMD_Bulldozer) d'AMD est connue sous le nom de code « [Piledriver](http://www.cpu-world.com/news_2012/2012011101_Features_of_AMD_Piledriver_processors.html) ». Elle promet un gain d'environ 15% en termes d'instructions par cycle d'horloge ([IPC](http://en.wikipedia.org/wiki/Instructions_per_clock)), de nouvelles instructions (FMA3, BMI, TBM) ainsi qu'une montée en fréquence permise par la très intrigante technologie Cyclos « [resonant clock mesh](http://www.cyclos-semi.com/technology/) ». GCC 4.7 prend d'ores et déjà en charge cette architecture « piledriver » de seconde génération et il est possible d'optimiser les binaires générés en passant l'option `-march=bdver2` lors de la compilation. Du côté d'Intel, l’option `-march=core-avx-i` est dédiée spécifiquement aux processeurs de type [Ivy Bridge](http://en.wikipedia.org/wiki/Ivy_Bridge_%28microarchitecture%29) et elle permet d'utiliser trois nouvelles instructions ajoutées dans [AVX](http://en.wikipedia.org/wiki/Advanced_Vector_Extensions). On trouve donc `FSGSBASE` pour manipuler les registres FS/GS, `F16C` pour convertir efficacement des nombres flottants 16 bits et enfin `RDRND` pour exploiter le générateur matériel de nombres aléatoires [Bull Mountain](https://linuxfr.org/news/le-noyau-linux-3-2-est-disponible#toc_13). Le support de la génération suivante des processeurs Intel, la puce [Haswell](http://en.wikipedia.org/wiki/Haswell_%28microarchitecture%29) qui sortira en 2013, est également déjà intégrée dans cette version de GCC. Ces processeurs intégreront le jeu d'instructions vectorielles [AVX2](http://en.wikipedia.org/wiki/AVX2#Advanced_Vector_Extensions_2) qui est très largement étendu par rapport à AVX (manipulation d'entiers sur 256 bits, opération de multiplication-accumulation à trois opérandes, etc). Ce support d'AVX2 est contrôlé dans GCC par l'option `-march=core-avx2`. ##Architecture ARM Il n'y a pas que les x86 dans la vie et l'architecture ARM à le vent en poupe en ce moment. [Cet article du site LWN](https://lwn.net/Articles/444238/) fait le point sur l'organisation [Linaro](http://en.wikipedia.org/wiki/Linaro) qui regroupe plusieurs industriels travaillant à un meilleur support ARM dans le monde du libre. Par exemple une équipe dédiée GCC, le _toolchain working group_, a développé des patchs permettant le support du processeur [Cortex-A7](http://www.arm.com/products/processors/cortex-a/cortex-a7.php) (le petit frère très économe du puissant Cortex-A15). Le compilateur GCC 4.7 du projet GNU intégre donc le résultat de ce travail et la compilation vers ce type de processeur s'active avec l'option `-mcpu=cortex-a7`. D'autre part, toujours dans le monde ARM, on peut noter un changement qui concerne la gestion de l'untité vectorielle [SIMD](http://fr.wikipedia.org/wiki/SIMD) de type [NEON](http://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD_.28NEON.29). À partir de GCC 4.7 la taille des vecteurs sera de 128 bits par défaut lors des passes d'auto-vectorisation avec un secours (_fallback_) en 64 bits en cas d'échec. On peut forcer l'ancien comportement avec la nouvelle option `-mvectorize-with-neon-double`. ##Architecture Sparc Plus exotique et moins tendance que l'architecture ARM, on trouve également dans cette nouvelle version de GCC diverses optimisations pour [SPARC](http://en.wikipedia.org/wiki/SPARC). Le support pour le [SPARC T3](http://en.wikipedia.org/wiki/UltraSPARC_T3), avec 16 coeurs in-order et 8 threads par coeur, et du [SPARC T4](http://en.wikipedia.org/wiki/SPARC_T4), avec 8 coeurs [out-of-order](http://fr.wikipedia.org/wiki/Ex%C3%A9cution_out-of-order) et 8 threads par coeur, [a été ajouté par David Miller](http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00256.html). Si vous voulez que vos binaires exploitent au mieux ces modèles de processeurs, il vous faudra passer les options `-mcpu=niagara3` ou `-mcpu=niagara4` lors de la compilation. C'est également David Miller qui s'est occupé [d'écrire les patchs](http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00830.html) permettant à GCC d'exploiter la fonction FMA pour SPARC. Cette fonction FMA, pour **F**used **M**ultiply–**A**dd, permet de faire en une seule étape une multiplication suivie d'une addition. En ce qui concerne le jeu d'instruction vectoriel SPARC VIS 2.0, qui s'active avec l'option `mvis2`, il est encore mieux pris en charge dans cette version du compilateur GNU. Les instruction `BSHUFFLE` (concaténation de deux registres flottants 64 bits) et `BMASK` (addition de deux entiers avec masquage des derniers 32 bits [de poids faible](http://fr.wikipedia.org/wiki/Bit_de_poids_faible)) sont maintenant pleinement supportées. ##Link Time Optimization La fonction d'optimisation lors de l'édition des liens ([Link Time Optimization](http://gcc.gnu.org/wiki/LinkTimeOptimization)) qui avait fait une entrée en fanfare dans [la version 4.5 de GCC](https://linuxfr.org/news/sortie-de-gcc-45), a été très largement améliorée lors de ce cycle de développement. C'est tout d'abord la consommation mémoire qui a fait l'objet d'une attention soutenue de la part des développeurs. Sur les systèmes 64 bits, une passe d'optimisation des liens lors de la compilation de Firefox ne nécessite plus que 3 Go de mémoire au lieu de 8 Go précédemment. L'étape non parallélisable de [l'édition des liens](http://fr.wikipedia.org/wiki/%C3%89dition_de_liens) a également été améliorée puisque les développeurs ont mesuré un gain **d'un ordre de magnitude** en vitesse ! Enfin on note également un progrès en matière de souplesse d'utilisation puisque l'édition des liens incrémentale (option `-r` de ld) est maintenant compatible avec la technique de Link Time Optimization. ##Fortran Le support des versions modernes du langage [Fortran](http://fr.wikipedia.org/wiki/Fortran) devient plus complet dans GCC 4.7. La possibilité d'utiliser la programmation orientée objet, introduit par la norme [Fortran 2003](http://en.wikipedia.org/wiki/Fortran#Fortran_2003), s'améliore avec le support des « polymorphic arrays ». En ce qui concerne [Fortran 2008](http://en.wikipedia.org/wiki/Fortran#Fortran_2008) et sa gestion du parallélisme, on peut maintenant utiliser `DO CONCURRENT` pour indiquer au compilateur les boucles de code sans interdépendances. Le support du modèle d'exécution [Co-array Fortran](http://en.wikipedia.org/wiki/Co-array_Fortran) a été également grandement amélioré pour le mode simple image. Le mode multi-image n'est pas encore intégré et il n'est que partiellement supporté via une bibliothèque nommée [Coarray Communication Library](http://gcc.gnu.org/wiki/CoarrayLib). Toujours pour Fortran on trouve également des changements dans la gestion des erreurs (`-fbacktrace` est activé par défaut) et la nouvelle option de compilation `-fstack-arrays` qui met tous les tableaux dans la pile mémoire. Dans certains cas cela peut augmenter grandement les performances. ##OpenMP Un domaine dans lequel GCC reste très en avance par rapport à son concurrent LLVM est celui du support de la norme [OpenMP](http://en.wikipedia.org/wiki/OpenMP). Cette interface de programmation permet de faire du calcul parallèle sur les architectures à mémoire partagée en introduisant notamment des directives à la compilation de type `#pragma omp`. La toute dernière [spécification 3.1](http://openmp.org/wp/openmp-specifications/) d'OpenMP, sortie en juillet 2011, est maintenant officiellement supportée par GCC 4.7 pour les langages C, C++ et Fortran. Même s'il ne s'agit que d'une mise à jour de la norme 3.0 parue en 2008, on trouve quand même certaines nouveautés intéressantes comme, par exemple, la possibilité d'assigner des fils d'exécution à des processeurs spécifiques (_bind threads_). ##Nouvelles architectures Le support de plusieurs nouvelles sortes de processeurs exotiques a été ajouté dans GCC 4.7. On trouve notamment [la famille C6X](http://en.wikipedia.org/wiki/C6x#C6000_Series) de Texas Instruments dont le port dans GCC a été assuré par la firme CodeSourcery (et qui a fait également [son apparition dans le noyau 3.3](http://linuxfr.org/news/sortie-du-noyau-linux-3-3#toc_16)). Il s'agit d'une nouvelle génération de DSP avec instructions 256 bits de type [VLIW](http://fr.wikipedia.org/wiki/Very_Long_Instruction_Word) (Very Long Instruction Word). A l'autre extrémité du spectre en matière de puissance on peut citer [le support dans GCC 4.7](http://gcc.gnu.org/ml/gcc-patches/2011-11/msg00108.html) de la puce Renesas RL78. C'est un micro-contrôleur 8/16 bits à faible consommation et qui a une architecture très proche du mythique [Z80](http://fr.wikipedia.org/wiki/Zilog_Z80). Enfin, dernier ajout notable, la société [Embecosm](http://www.embecosm.com/) qui est spécialisée dans l'embarqué, a écrit le code permettant le support de l'architecture [Adapteva Epiphany](http://en.wikipedia.org/wiki/Adapteva#Products) dans cette version de GCC. Ce nouveau processeur est formé d'une multitude de coeurs RISC très simples partageant un espace mémoire unique et reliés par un réseau en [topologie maillée](http://fr.wikipedia.org/wiki/Topologie_mesh) (un peu comme les puces de [Tilera](http://en.wikipedia.org/wiki/TILE64)). ##Nouvelles commandes En ce qui concerne les nouvelles commandes disponibles dans GCC 4.7 la liste est longue mais on peut citer [la possibilité](http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#index-fdisable_002d-561) d'activer (avec `-fenable`) ou de désactiver (avec `fdisable`) chacune des passes d'optimisation individuellement. On obtient facilement la liste des passes qui sont activées ou pas avec la commande `-fdump-passes`. La commande `-Wstack-usage=len` permet [d'activer une alerte](http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options) si la taille de la pile dépasse la valeur spécifiée par `len`. La commande `-Wvector-operation-performance` est utile au moment du travail d'amélioration des performances du programme puisqu'[elle envoie une alerte](http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wno_002dvector_002doperation_002dperformance-501) si des opérations portant sur des vecteurs ne sont pas implémentés via le module [SIMD](http://fr.wikipedia.org/wiki/SIMD) du processeur. ##Nouvelles optimisations Diverses passes d'optimisations ont été ajoutées dans GCC 4.7 et plusieurs passes qui existaient déjà ont été améliorées. On peut citer par exemple la nouvelle passe `-foptimize-strlen` qui s'occupe des multiples fonctions de manipulations de chaînes de caractères de votre code: `strlen()`, `strchr()`, `strcpy()`, `strcat()` et `stpcpy()`. Quand elle est activée, cette passe va regarder les endroits dans votre code qui utilisent ces fonctions et va chercher à remplacer ces parties par du code optimisé plus rapide (voir [les explications de Jakub Jelinek](http://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg14792.html) avec un exemple de code). Une autre passe intéressante qui a été ajoutée est `-ftree-tail-merge`. Ici il s'agit de regarder les séquences de code identiques à la fin des fonctions. Quand une seconde séquence semblable est trouvée alors le code est simplement remplacé par un `jump` vers la première séquence. Comme cette passe est coûteuse en temps de compilation il est possible d'indiquer une limite avec la commande `max-tail-merge-comparisons`. Un autre exemple de nouvelle passe d'optimisation intégrée dans GCC 4.7 est l'option `-fshrink-wrap` qui modifie les prologues de fonctions. En assembleur les fonctions sont précédées par des « [prologues](http://en.wikipedia.org/wiki/Function_prologue) », c'est à dire des lignes de code qui vont préparer un espace sur la pile. Normalement GCC ne se pose pas de question et il insère ce prologue en tête de la fonction. Avec `-fshrink-wrap` l'insertion du prologue ne se fera plus de façon aussi générique mais juste avant les parties de la fonction qui en ont vraiment besoin. D'après [Nick Clifton](http://nickclifton.livejournal.com/9396.html):> _Cette optimisation sera particulièrement utile pour améliorer les scores des benchmarks synthétiques du type dhrystone ou coremark._ ## C++11 Le travail sur la prise en charge de [la norme ISO C++11](http://en.wikipedia.org/wiki/C%2B%2B11) continue dans cette nouvelle version du compilateur GNU. Parmi les nombreuses nouveautés (template aliases, delegating constructors, etc) on peut notamment remarquer tout ce qui tourne autour de la gestion de la mémoire et des threads. Il s'agit [d'un des points clés de C++11](http://en.wikipedia.org/wiki/C%2B%2B11#Threading_facilities) qui a pour ambition de proposer aux programmeurs de nouveaux outils pour gérer la concurrence. On retrouve donc les fonctions préfixés par `__atomic` qui remplacent les anciennes `__sync` et on note également les options `-finline-atomics` et `-Winvalid-memory-model` liées à ces fonctions. Il faudra toutefois attendre GCC 4.8 pour bénéficier de la bibliothèque `libatomic` qui est utilisé en dernier recours quand il n'est pas possible d'avoir des instructions sans verrous. [Une page du wiki GCC](http://gcc.gnu.org/wiki/Atomic/GCCMM) est dédiée à ces questions complexes de gestion de la mémoire avec C++11. ## C11 Du côté du bon vieux langage C il y a là aussi des nouveautés puisque les développeurs de GCC travaillent sur [la norme C11](http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29) (voir [cette dépêche LinuxFr de GeneralZod](http://linuxfr.org/news/c11-nest-pas-encore-mort) pour un récapitulatif des nouveautés). Quand on active l'option `-std=c11` on retrouve donc la gestion des chaînes unicode et des macros `__STDC_UTF_16__` et `__STDC_UTF_32__`. GCC 4.7 intégre les fonctions d'alignement `_Alignas` et `_Alignof`, la gestion du mot-clé `_Noreturn`, la fonction `__builtin_complex` pour profiter des macros CMPLX, etc. Maintenant que la norme C11 a été [officiellement ratifié par l'ISO](http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=57853) le 8 décembre 2011, il est probable que le travail d'intégration dans GCC va s'accélerer. ##Extensions GNU pour DWARF Quand on veut traquer les bugs d'un programme il faut utiliser un débogueur, [GDB](http://en.wikipedia.org/wiki/Gdb) par exemple. Pour faire son travail, ce débogueur va se servir [des diverses informations](http://en.wikipedia.org/wiki/Debugging_data_format) générées lors de la compilation et qui ont été stockées dans l’exécutable [ELF](http://en.wikipedia.org/wiki/Executable_and_Linkable_Format) (**E**xecutable and **L**inkable **F**ormat). Le format de ces informations de débogage se nomme [DWARF](http://en.wikipedia.org/wiki/DWARF) (elfe, nain...humour) et, [depuis juin 2010](http://dwarfstd.org/Announcement.php), nous en sommes à la version 4 de ce format. GCC 4.7 propose plusieurs nouvelles extensions qui sont spécifiques au [projet GNU](http://www.gnu.org/) et qui permettent d'étendre les fonctionnalités de DWARFv4. On trouve par exemple `DW_OP_entry_value` qui suit les valeurs passées en argument des fonctions ou encore `DW_TAG_call_site` qui repère mieux les appels de fonction (ces deux extensions feront sans doute partie de DWARFv5 : [1](http://www.dwarfstd.org/ShowIssue.php?issue=100909.1) - [2](http://www.dwarfstd.org/ShowIssue.php?issue=100909.2)). Un autre ajout fort utile consiste à remplacer la section `debug_macinfo` classique du format DWARF par une nouvelle section nommée `debug_macro`. Habituellement la section `debug_macinfo`est utilisée pour stocker un tableau de correspondance (_lookup table_) de tous les objets globaux et de toutes les fonctions. On comprend donc que ce tableau puisse atteindre des tailles démesurées (plusieurs centaines de Mo). Le développeur Jakub Jelinek [a eu l'idée](http://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg10419.html) de ne stocker que les informations non redondantes en mettant à profit les informations de la section `debug_str` qui existe déjà. Selon [les tests effectués](http://www.dwarfstd.org/ShowIssue.php?issue=110722.1http://somesite.com/) le gain est saisissant puisqu'on passe de 350 Mo stockées dans `debug_macinfo` à seulement 1 Mo dans `debug_macro` plus 1,5 Mo de données additionnelles dans `debug_str`. Un gain d'un facteur 100 ! Bien entendu, si vous n'aimez pas ces extensions GNU qui ne sont pas encore standardisés dans le format DWARF, alors vous pouvez passer l'option `-gstrict-dwarf` et vous retrouverez le comportement précédent. #Le futur de GCC Contrairement aux autres années, il n'y a [pas eu de sommet GCC en 2011](http://gccsummit.org/2011/). La prochaine réunion officielle, le [GCC Summit 2012](http://gccsummit.org/2012/), est prévue pour les 23, 24 et 25 mai prochain. Lors de l'année écoulée, les développeurs et les chercheurs de la communauté GCC ont cependant eu plusieurs occasions d'échanger leurs idées. On peut citer notamment le workshop « GROW 2011 » (GCC Research Opportunities) qui s'est déroulé en avril. Les articles présentés à cette occasion [sont disponibles](http://grow2011.inria.fr/index.php?option=com_content&view=article&id=57&Itemid=61) sur le site de l'INRIA. On peut également évoquer la rencontre « [GCC Gathering 2011](http://gcc.gnu.org/wiki/GCCGathering2011) » de juin dernier dans les locaux londoniens de Google. Le [compte-rendu au format pdf](http://gcc.gnu.org/wiki/GCCGathering2011?action=AttachFile&do=get&target=GCCGathering2011.pdf) est disponible sur le wiki du projet. Toutes ces rencontres permettent aux développeurs de tenter de définir en commun ce que doit être le futur de GCC. De nombreuses améliorations sont prévues pour la prochaine version 4.8 (voir par exemple [les projets](http://gcc.gnu.org/wiki/Graphite-4.8) concernant l'infrastructure [Graphite](http://gcc.gnu.org/wiki/Graphite)) mais qu'en est-il du long terme ? On sait que l'adoption en 2005 de la technique SSA (**S**tatic **S**ingle **A**ssignement) avait été jugée suffisament importante pour [passer GCC en version 4](http://linuxfr.org/news/sortie-de-gcc-40). Des discussions sont actuellement en cours qui pourraint bien conduire, à terme, au passage en version 5 du compilateur GNU. Cette fois c'est [la modularisation de l'architecture](http://gcc.gnu.org/wiki/ModularGCC) qui justifierait ce saut de version. En décembre dernier Diego Novillo et Joseph Myers ont publié en ligne [un très intéressant document](https://docs.google.com/document/pub?id=1ZfyfkB62EFaR4_g4JKm4--guz3vxm9pciOBziMHTnK4&pli=1) sur l'architecture de GCC. Le but était de passer en revue tous les axes d'améliorations possibles (listés dans [une page annexe du wiki](http://gcc.gnu.org/wiki/ImprovementProjects)) afin d'assurer la pertinence à long terme du projet. Un point important de cette remise à plat concerne la modularisation de GCC qui, très récemment, a suscité de nombreux échanges sur la liste de diffusion du projet. David Malcolm, employé par Red Hat mais parlant en son nom, a envoyé [un long mail](http://gcc.gnu.org/ml/gcc/2012-03/msg00256.html) sur cette liste de diffusion. Dans son message il souligne le fait que [le compilateur LLVM](http://llvm.org/) rencontre du succès, en tant que [JIT](http://fr.wikipedia.org/wiki/Compilation_%C3%A0_la_vol%C3%A9e), grâce à son architecture modulaire. Selon lui il faut que GCC adopte progressivement ce modèle en composants disjoints puisqu'il facilite la réutilisation par d'autres projets. Basile Starynkevitch est également intervenu sur ce sujet avec [un mail](http://gcc.gnu.org/ml/gcc/2012-03/msg00263.html) qui cite à plusieurs reprises [GTK](http://www.gtk.org/) comme exemple à suivre au point de vue de la modularisation. [La page consacrée à la modularisation](http://gcc.gnu.org/wiki/ModularGCC) dans le wiki GCC n'a pas encore été mise à jour mais on peut penser que les discussions en cours vont permettre de faire avancer la réflexion sur ce sujet.