Sortie de GCC 7.1

66
24
juin
2017
GNU

La sortie de la nouvelle version majeure du compilateur GCC du projet GNU a été annoncée le 2 mai 2017. É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 sources écrits en C, C++, Objective-C, Fortran, Java, Go et Ada et fonctionne sur une multitude d’architectures.

La suite de la dépêche vous propose une revue de certaines améliorations et nouvelles fonctionnalités de cette nouvelle version.

GCC

Sommaire

Mais que veut dire GCC ?

En août 1987, GCC signifiait GNU C Compiler (compilateur C de GNU) car il ne prenait en charge que le langage de programmation C. Mais dès décembre 1987, la prise en charge expérimentale du C++ a été intégrée (stabilisée avec GCC 2 publié en 1992). Six autres langages de programmation seront pris en charge progressivement (Objective-C, Objective-C++, Fortran, Java, Ada, et Go).

Le divergence (fork) EGCS a commencé à avoir du succès. Après une longue période de négociation, les deux projets se sont finalement réunifiés en avril 1999 pour donner un nouveau nom : GNU Compiler Collection, en conservant le même acronyme que le projet original. La première version du nouveau projet fut GCC 2.95.

Donc, depuis 1999, GCC signifie GNU Compiler Collection et prend en charge neuf langages de programmation (et bien d’autres expérimentalement ou avec des extensions).

Collection de langages de programmation

  1. C, avec gcc ;
  2. C++, avec g++ ;
  3. Objective-C ;
  4. Objective-C++ ;
  5. Fortran, avec gfortran ;
  6. Java, avec gcj (qui est mort) ;
  7. Ada, avec GNAT ;
  8. Go, avec gccgo ;
  9. OpenMP (c’est un langage qui étend d’autres langages de programmation) ;
  10. Cilk Plus ;
  11. OpenACC ;
  12. Unified Parallel C avec le GCC UPC compiler (expérimental).

Des logiciels tiers (third parties) permettent la prise en charge d’autres langages :

  1. Pascal, avec gpc ;
  2. Modula (2 et 3) ;
  3. PL/I ;
  4. D, avec gdc ;
  5. VHDL, avec ghdl.

Schéma de version

Le projet GCC a modifié son schéma de version en août 2014 pour faire coïncider l’année 2015 à la version GCC 5 et ainsi de suite pour donner : 2016 → GCC 6, puis 2017 → GCC 7. Attention, nous devrions donc avoir GCC 10 en 2020.

Détail des versions avec le nouveau schéma :

Branche de
développement      (2014-04-11) 
de GCC 4.10
 |
 |
GCC 4.10 renommée  (2014-08-13)
GCC 5.0
 |
 |
Branche de
développement
de GCC 5
 | 
 +-------- Branche de livraison
 |         GCC 5.x (2015-04-12)
 |                 |
 |                 v
 |         GCC 5.1 (2015-04-22)
 |                 |
 |                 v
Branche    GCC 5.2 (2015-07-16)
de dév.            |
GCC 6              v
 |         GCC 5.3 (2015-12-04)
 |                 |
 |                 v
 |         GCC 5.4 (2016-06-03)
 |\
 | \
 |  `----- Branche de livraison
 |         GCC 6.x (2016-04-15)
 |                 |
 |                 v
 |         GCC 6.1 (2016-04-27)
 |                 |
Branche            v
de dév.    GCC 6.2 (2016-08-22)
GCC 7              |
 |                 v
 |         GCC 6.3 (2016-12-21)
 |\
 | \
 |  `----- Branche de livraison
 |         GCC 7.1 (2017-05-02)
 |                 |
 v                 |
Branche            v
de dév.    Branche de correction
GCC 8       de bogues sur GCC 7

timeline

Nouveautés spécifiques à un ou des langages

Ada

Sur les plates‐formes les plus courantes, les programmes Ada n’ont plus besoin que la pile soit exécutable pour fonctionner correctement.

BRIG (HSAIL)

Prise en charge de BRIG 1.0. BRIG est un format binaire pour HSAIL (Heterogeneous System Architecture Intermediate Language).

Famille C/C++

Les langages C et C++ partagent les améliorations suivantes :

  • en cas d’erreur (de frappe) sur le nom d’une variable membre, GCC 6 pouvait déjà suggérer un nom correct. GCC 7 va encore plus loin et détectant des noms mal orthographiés de fonctions, macros, types, énumérations, etc. ;
  • le préprocesseur suggère aussi une correction si une directive est mal écrite ;
  • ajout des contrôles de débordement pour les opérations arithmétiques, __builtin_add_overflow_p,__builtin_sub_overflow_p et __builtin_mul_overflow_p ; contrairement à leurs équivalents sans le _p final, ceux‐ci ne demandent pas d’argument pour ranger le résultat de l’opération.

Améliorations spécifiques au langage C

  • -fopenmp comprend le mot‐clef _Atomic de C11 ;
  • ajouts des types flottants étendu, FloatN et FloatNx ; la disponibilité de ces types dépend de l’architecture utilisée.

Améliorations spécifiques au langage C++

  • prise en charge expérimentale de C++17 (-std=c++1z) ;
  • l’ordre d’évaluation des expressions peut être activé hors C++17 (-fstrong-eval-order) ou désactivé pour ce dernier (-fno-strong-eval-order) ;
  • implémentation des fonctionnalités C++17 au sein de la libstdc++.

Fortran

La version 4.5 de la spécification OpenMP est maintenant partiellement gérée par le compilateur Fortran.

Go

  • il y a une implémentation complète des paquets utilisateurs de Go 1.8.1 ;
  • par rapport à la chaîne de compilation de Go 1.8.1, le ramasse‐miettes est plus conservateur et moins concurrent ;
  • -fgo-optimize-allocs et -fgo-debug-escape

Java

Java (GCJ) n’existe plus (mais le code est toujours disponible via le gestionnaire de versions).

Diagnostics

Pour aider à la correction de bogues, GCC 7 apporte ces directives intéressantes :

  • -fdiagnostics-parseable-fixit : les suggestions de correction sont diffusées sous un format plus lisible et capable d’être mieux digéré par les EDI ;
  • fdiagnostics-generate-patch : produit un fichier correctif dans le format unifié (patch -u) à la fin du diagnostic.

Délestage

Depuis la version 5, deux implémentations sont proposées pour délester, complètement ou partiellement, l’exécution de code par un processeur externe (c.‐à‐d. un ou plusieurs processeurs graphiques) : OpenACC et OpenMP.

Cette version améliore la prise en charge des spécifications OpenACC 2.0A et autorise le délestage de régions openMP par les processeurs graphiques NVIDIA (PTX).

Ces deux interfaces sont accessibles via la bibliothèque libgomp.

Divers

  • # Délester ?

    Posté par . Évalué à 7 (+9/-4).

    En général, quand on se lâche du lest, il se perd dans la nature… Plutôt que délester, j'aurais donc dit déléguer l'exécution de code à un GPU.

    • [^] # Re: Délester ?

      Posté par (page perso) . Évalué à 2 (+2/-1).

      Si l'on veut rester pédant dans la définition, «déléguer» ne convient pas non plus: il n'est pas question là d' autorité ou de représentation.

      GCC n'est pas l'initiateur: c'est un choix du développeur.

      GCC est débarrassé d'une charge, comme un axe routier se retrouve soulagé par un itinéraire de délestage.

      • [^] # Re: Délester ?

        Posté par . Évalué à 6 (+5/-1). Dernière modification le 25/06/17 à 11:51.

        D'après le Larousse en ligne :

        « Envoyer quelqu'un au nom d'un groupe, de quelqu'un d'autre, dans un but déterminé, avec une mission définie ». Bon, le GPU n'est pas une personne, mais à part ça, la définition colle : le GPU se voit confier, au nom du CPU (qui conserve son rôle de chef d'orchestre), l'exécution d'une mission définie.

    • [^] # Re: Délester ?

      Posté par (page perso) . Évalué à 10 (+9/-0).

      Au contraire, c'est correct : délester prend le sens de décharger : retirer une partie de la charge — de quelqu'un ou quelque chose. Qui a donné par suite délestage, dans itinéraire de délestage. On ne jette donc pas du lest, mais on emprunte une autre voie. Le terme est judicieux.

      "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

      • [^] # Re: Délester ?

        Posté par . Évalué à 3 (+2/-0).

        Le mot délester ne me choque pas ici, par contre c'est c'est l'emploi de par dans "délester par …" qui sonne bizarrement pour moi. J'aurais plutôt écrit "délester vers".

      • [^] # Re: Délester ?

        Posté par . Évalué à 4 (+3/-1).

        En anglais on dirait "offload", donc plutôt "décharger".
        Où simplement "déplacer".

  • # Performances

    Posté par . Évalué à 8 (+6/-0). Dernière modification le 01/07/17 à 01:46.

    Outre le fait que GCC ait mis en exergue un gros bug qui fait que sous certaines conditions de charge CPU, les processeurs Intel Skylake et Kabylake peuvent crasher et planter complètement le système (Linux comme Windows), j'ai vu passer un tableau de benchmarks qui m'a interpellé.

    En effet, dans le cadre de l'annonce de la gamme Epyc d'AMD, le site Heise.de a procédé à différents tests comparatifs pour l'évaluer, et l'un d'entre eux consistait à comparer — sous Linux — les performances SPEC CPU 2006 de différents processeurs, avec des programmes compilés avec différents compilateurs (enfin, me semble-t-il, je ne pane rien à l'allemand).

    Si je comprends bien le tableau, cela veut-il dire que — dans ce test précis — GCC 6.3-02 est significativement moins performant qu'Open64 v4.5.2.1 et Intel 2016 ?

    AMD Epyc 7601 - Spec CPU 2006

    Si tel était le cas, GCC 7.1 améliore-t-il la chose ?

    • [^] # Re: Performances

      Posté par . Évalué à 3 (+1/-0).

      Je ne connais pas open64 (compilateur pour architecture un peu particuliere et qui en fin de vie) par contre il est bien connu que le compilo intel est bien plus optimise que GCC et … bien plus bugge… ou disons bien moins respectueux des normes. Si ton code passe a la compilation cela peut etre cool mais bon il y a souvent du boulot d'adaptation a faire pour contourner les problemes.

    • [^] # Re: Performances

      Posté par . Évalué à 10 (+10/-0).

      Dans l'article cité, les auteurs utilisent GCC avec l'optimisation au niveau 2 (-O2) et non pas 3 (-O3). Cela peut expliquer largement la différence de performance.
      Ensuite, ils devraient utiliser le flag -Ofast pour le code en virgule flottante : le compilateur d'Intel n'est pas aussi strict sur la norme que GCC. En particulier, il considère par défaut que les opérations sont commutatives (a + b = b + a) et associatives (a + (b + c) = (a + b) + c), ce qui n'est pas vrai en virgule flottante… et permet de nombreuses optimisations !

      En outre, ils précisent qu'ils n'ont pas spécifié d'architecture (flag -march=native par exemple).
      Dans ce cas, GCC optimise de sorte à se comporter convenablement sur un ensemble de processeurs cible. Ainsi, il optimise bien moins le code pour Ryzen qu'avec une architecture spécifique.
      Le compilateur d'Intel détecte l'architecture automatiquement (fut un temps ils se comportaient moins bien, délibérément, pour les processeur d'AMD).
      Open64 a été maintenu par AMD, c'est normal qu'il se comporte bien sur les processeurs d'AMD.

      Ce serait intéressant de comparer GCC en activant la détection d'architecture (ou en spécifiant carrément l'architecture du processeur ciblé) et un niveau d'optimisation comparable vis-à-vis des normes !

  • # Divergence

    Posté par (page perso) . Évalué à 1 (+0/-1). Dernière modification le 10/07/17 à 18:33.

    On dit « Le divergence » ou « Le dérivé » ?

    • [^] # Re: Divergence

      Posté par (page perso) . Évalué à 2 (+1/-1).

      Wikipédia énonce :

      Un fork, en français fourche ou encore embranchement […]

      L'« embranchement » me semble approprié ici comme formulation. Mais ça fait moins Holywood.

      Adhérer à l'April, ça vous tente ?

  • # Changement non mentionné

    Posté par (page perso) . Évalué à 2 (+0/-0).

    Je ne l’ai pas trouvé dans les changements de GCC 7 ou 7.1, mais avr-gcc est plus strict dans certains cas et empêche du code de compiler du code qui était accepté auparavant. J’ai dû corriger le code de QMK pour pouvoir le compiler avec la dernière version de GCC.

    Écrit en Bépo selon l’orthographe de 1990

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.