Introducing GNU Compiler Collection (GCC) and Clang/Low Level Virtual Machine (LLVM); comparing the performance of both C/C++ compilers
Visual C++, GNU Compiler Collection (GCC), and Clang/Low Level Virtual Machine (LLVM) are three mainstream C/C++ compilers in the industry. Visual C++ fournit des interfaces utilisateur graphiques (GUI) et est facile à déboguer, mais il ne convient pas aux plates-formes Linux. Par conséquent, ce document compare principalement GCC avec Clang/LLVM.
GCC est un compilateur de langage de programme développé par GNU. C’est un ensemble de logiciels libres publiés sous la Licence Publique Générale GNU (GPL) et la Licence Publique Générale Moindre GNU (LGPL). C’est un compilateur officiel pour les systèmes GNU et Linux, et un compilateur principal pour compiler et créer d’autres systèmes d’exploitation UNIX.
LLVM contient une série de composants de compilateur modularisés et de chaînes d’outils. Il peut optimiser les langages de programme et les liens pendant la compilation, l’exécution et le temps d’inactivité et générer du code. LLVM peut servir d’arrière-plan pour les compilateurs dans plusieurs langues. Clang est un compilateur C, C++, Objective-C ou Objective-C++ compilé en C++ basé sur LLVM et publié sous la licence Apache 2.0. Clang est principalement utilisé pour fournir des performances supérieures à celles de GCC.
Grâce au développement et à l’itération à long terme, GCC, Clang et LLVM sont devenus des compilateurs matures dans l’industrie. Alors, quel compilateur est le meilleur? Lequel devrions-nous utiliser pour compiler et construire des programmes et des systèmes?
Importance d’un bon compilateur
Les processeurs modernes ont tous des pipelines superscalaires et longs, et des structures internes complexes, et ils prennent en charge des unités d’extension vectorielle dans l’architecture Computer Instruction Set Computer (CISC) ou Reduced Instruction Set Computer (RISC). Pour de nombreux programmes contenant des noyaux à forte intensité de calcul, les programmeurs peuvent utiliser des commandes d’extension vectorielle pour améliorer considérablement les performances d’exécution du programme. Par exemple, dans les opérations matricielles et vectorielles, les commandes combinées de multiplication et d’addition sont utilisées pour améliorer les performances et la précision. Les commandes de masque de bits sont utilisées pour le traitement de branches dans les opérations vectorielles. Cependant, pour obtenir les meilleures performances, les programmeurs et les compilateurs doivent encore déployer beaucoup d’efforts pour gérer les tâches avec des modes d’accès mémoire complexes et des noyaux non standard.
De plus, les normes des langages avancés modernes abstraient constamment les détails des structures matérielles et de données sous-jacentes pour générer un code général plus logique et mathématique, au lieu d’instructions de fonctionnement spécifiques et de chemins d’accès à la mémoire. Les normes C++ sont de plus en plus expressives et abstraites. Python est populaire car il est plus lisible et expressif, même au prix d’une vitesse de fonctionnement inférieure. Une expressivité plus élevée augmente la charge du compilateur de générer un bon code d’assemblage à partir des structures complexes compilées par les programmeurs. Le compilateur doit être plus intelligent et travailler plus fort pour maximiser les performances en utilisant le code. Tous les compilateurs ne peuvent pas le faire. Lors de la sélection d’un compilateur, nous devons d’abord considérer si le même segment de code peut générer des commandes d’assemblage plus efficaces.
En plus de générer des programmes exécutables hautes performances, les compilateurs modernes doivent également avoir eux-mêmes des performances élevées. Un projet logiciel de grande taille en C++ peut contenir des centaines à des milliers d’unités de traduction individuelles. Chaque unité de traduction peut contenir des milliers de lignes de code. Le code C++ peut également utiliser un grand nombre de technologies de programmation basées sur des modèles. Ces technologies nécessitent que le compilateur transfère plusieurs fois des informations pertinentes pour générer un fichier cible. La compilation de projets C++ de grande taille peut prendre plusieurs heures, et plusieurs modifications mutuellement dépendantes doivent être soumises simultanément pendant le développement. Chaque soumission nécessite que les développeurs recompilent la plupart des bibliothèques de code. Par conséquent, des compilateurs plus rapides (outils de construction) sont essentiels pour atteindre une productivité élevée pour les grandes équipes.
En termes d’extension du langage, les systèmes informatiques modernes à noyaux multiples, les capacités de traitement vectoriel et les accélérateurs offrent des capacités supérieures aux capacités naturelles des langages de programmation courants. Par conséquent, des frameworks de calcul haute performance (HPC) spécifiques, tels qu’OpenMP et OpenACC, peuvent combler cette lacune. Ces frameworks fournissent des interfaces de programme d’application (API) que les programmeurs peuvent utiliser pour exprimer le parallélisme dans le code. Le compilateur et la bibliothèque d’exécution correspondante doivent mapper le code parallèle à l’architecture du processeur. De nombreux projets HPC dépendent des normes OpenMP et OpenACC, qui sont étendues par les développeurs et les fabricants de matériel. Par conséquent, les compilateurs doivent suivre le développement des normes d’extension du langage.
En conclusion, un bon compilateur nous permet de nous concentrer sur le processus de programmation, plutôt que de lutter contre ses lacunes. Il peut prendre en charge les dernières normes linguistiques, générer des commandes optimisées à partir du code le plus abstrait et compiler le code source en moins de temps.
Historique du développement de GCC
Avant d’apprendre GCC, vous devez d’abord comprendre le projet GNU. Richard Stallman a lancé le projet GNU en 1984 pour construire un système logiciel open source de type UNIX. Le système d’exploitation GNU n’a pas beaucoup évolué au fil du temps. Cependant, il a incubé de nombreux outils logiciels open source excellents et utiles, tels que Make, Sed, Emacs, Glibc, GDB et GCC. Ces logiciels libres GNU et les noyaux Linux constituent ensemble le système GNU/Linux. Au début, GCC fournissait des compilateurs stables et fiables, basés sur le langage de programmation C, pour le système GNU. Son nom complet est GNU C Compiler. Plus tard, d’autres langages (tels que Fortran, Obj-C et Ada) ont été pris en charge, et le nom complet de GCC a été changé en GNU Compiler Collection.
GCC-1.0 a été publié par Richard Stallman en 1987, il y a plus de trente ans. Du point de vue du logiciel, il est très ancien. Quelqu’un a collecté les enregistrements de développement de GCC entre 1989 et 2012, et a produit une vidéo animée de trente minutes (GNU Compiler Collection dev history 1989-2012), démontrant intuitivement le processus de développement de GCC. Nous pouvons en apprendre davantage sur l’histoire du développement de GCC à partir de ses versions:
- GCC-1.0: publié par Richard Stallman en 1987.
- GCC-2.0 : sortie en 1992 et prise en charge du C++. Plus tard, la communauté de GCC a été divisée parce que Richard Stallman a défini GCC comme un compilateur C fiable du système GNU et pensait que GCC à l’époque était suffisant pour le système GNU et que l’accent sur le développement devait être déplacé de GCC vers le système GNU lui-même. D’autres grands développeurs espéraient continuer à améliorer GCC et apporter des développements et des améliorations plus radicaux dans divers aspects. Ces développeurs actifs ont quitté la communauté GCC en 1997 et ont développé le fork EGCS.
- GCC-3.0: De toute évidence, les développeurs avaient généralement un fort désir de bons compilateurs. Le fork EGCS s’est développé en douceur et est devenu reconnu par de plus en plus de développeurs. Finalement, EGCS a été utilisé comme nouveau backbone GCC et GCC-3.0 a été publié en 2001. La communauté divisée fut à nouveau fusionnée, mais l’influence de Richard Stallman avait été affaiblie dans une certaine mesure. En outre, le Comité industriel du CCG avait commencé à décider de l’orientation du développement du CCG.
- GCC-4.0 : sortie en 2005. Cette version a été intégrée à l’architecture de stockage série Arborescente (SSA), et GCC a évolué pour devenir un compilateur moderne.
- GCC-5.0 : sortie en 2015. Plus tard, la politique de version du CCG a été ajustée et une version majeure a été publiée chaque année. Un avantage inattendu est que le numéro de version correspond à l’année. Par exemple, GCC-7 a été publié en 2017 et GCC-9 en 2019.
Maintenant, le développement de GCC est entré dans la « chronique moderne ». Face à la pression concurrentielle de LLVM, la communauté du CCG a activement apporté de nombreux ajustements, tels que l’accélération de la compilation et l’amélioration des informations d’avertissement de compilation. Au cours des 30 dernières années, GCC est passé d’un challenger dans l’industrie des compilateurs à un compilateur grand public pour les systèmes Linux, et fait maintenant face au défi de LLVM. Heureusement, la communauté GCC apporte des ajustements pour accélérer le développement de GCC. Nous pouvons nous attendre à ce que la concurrence entre les deux technologies de compilation continue de fournir aux développeurs de logiciels de meilleurs compilateurs.
L’histoire du développement de Clang et de LLVM
LLVM est née de la recherche de Chris Lattner sur l’UUIC en 2000. Chris Lattner voulait créer une technologie de compilation dynamique pour tous les langages statiques et dynamiques. LLVM est un type de logiciel open source développé sous licence BSD. La version initiale 1.0 a été publiée en 2003. En 2005, Apple Inc. a embauché Chris Lattner et son équipe pour développer des langages de programmation et des compilateurs pour les ordinateurs Apple, après quoi le développement de LLVM est entré dans la voie rapide. À partir de LLVM 2.5, deux versions mineures de LLVM ont été publiées chaque année (généralement en mars et septembre). En novembre 2011, LLVM 3.0 a été publié pour devenir le compilateur XCode par défaut. XCode 5 a commencé à utiliser Clang et LLVM 5.0 par défaut. La politique de version a été ajustée pour LLVM 5.0 et les versions ultérieures, et deux versions majeures sont publiées chaque année. La version stable actuelle est 8.0.
Le nom de LLVM a d’abord été abrégé de Machine virtuelle de Bas niveau. Comme ce projet ne se limite pas à la création d’une machine virtuelle, l’abréviation LLVM est souvent remise en question. Après le développement de LLVM, il est devenu un terme collectif pour de nombreux outils de compilation et technologies d’outils de bas niveau, rendant le nom moins approprié. Les développeurs ont décidé d’abandonner la signification de cette abréviation. Maintenant, LLVM est devenu le nom de marque officiel, applicable à tous les projets sous LLVM, y compris la Représentation intermédiaire LLVM (LLVM IR), les outils de débogage LLVM et les bibliothèques standard LLVM C++. LLVM peut être utilisé comme compilateur traditionnel, compilateur JIT, assembleur, débogueur, outil d’analyse statique et pour d’autres fonctions liées aux langages de programmation.
En 2012, LLVM a remporté le prix du système logiciel de l’Association for Computing Machinery (ACM), ainsi que des systèmes traditionnels tels qu’UNIX, WWW, TCP/IP, TeX et Java. LLVM simplifie grandement la mise en œuvre de nouvelles chaînes d’outils de langage de programmation. Ces dernières années, de nombreux nouveaux langages de programmation tels que Swift, Rust et Julia ont utilisé LLVM comme framework de compilation. De plus, LLVM est devenu le compilateur par défaut pour les systèmes Mac OS X, iOS, FreeBSD et Android.
Clang
Clang est conçu pour fournir un compilateur frontal pouvant remplacer GCC. Apple Inc. (y compris NeXT later) a utilisé GCC comme compilateur officiel. GCC a toujours bien fonctionné en tant que compilateur standard dans la communauté open source. Cependant, Apple Inc. a ses propres exigences pour les outils de compilation. D’une part, Apple Inc. ajout de nombreuses nouvelles fonctionnalités pour le langage Objective-C (ou même, plus tard, le langage C). Cependant, les développeurs de GCC n’ont pas accepté ces fonctionnalités et ont attribué une faible priorité à la prise en charge de ces fonctionnalités. Plus tard, ils ont simplement été divisés en deux branches pour un développement séparé, et par conséquent la version GCC publiée par Apple Inc. est bien plus tôt que la version officielle. D’autre part, le code GCC est fortement couplé et difficile à développer séparément. De plus, dans les versions ultérieures, la qualité du code continue de diminuer. Cependant, de nombreuses fonctions requises par Apple Inc. (comme le support amélioré de l’Environnement de développement intégré ( improved)) doit appeler GCC en tant que module, mais GCC ne fournit jamais un tel support. De plus, l’exemption de la bibliothèque d’exécution GCC limite fondamentalement le développement de LLVM GCC. Également limité par la licence, Apple Inc. impossible d’utiliser LLVM pour améliorer encore la qualité de génération de code basée sur GCC. Par conséquent, Apple Inc. décidé d’écrire le Clang frontend des langages C, C ++ et Objective-C à partir de zéro pour remplacer complètement GCC.
Comme son nom l’indique, Clang ne supporte que C, C++ et Objective-C. Le développement a commencé en 2007 et le compilateur C a été terminé pour la première fois. Clang pour Objective-C cloud sera entièrement utilisé pour l’environnement de production en 2009. La prise en charge du C++ a également progressé rapidement. Clang 3.3 entièrement pris en charge C ++ 11, Clang 3.4 entièrement pris en charge C ++ 14 et Clang 5 entièrement pris en charge C ++ 17, et tous étaient nettement en avance sur GCC à cette époque.
Clang/LLVM et communauté GCC
Comme les autres communautés de logiciels open source, la communauté GCC est dominée par les passionnés de logiciels libres et les hackers. En cours de développement, les mécanismes de gestion communautaire et de participation du CCG se forment progressivement aujourd’hui. Actuellement, la communauté du CCG est une société de connaissance relativement stable et bien définie dans laquelle chaque personne a des rôles et des devoirs clairs:
- Richard Stallman et la Free Software Foundation (FSF): Bien que rarement impliqués dans la gestion de la communauté du CCG, Richard Stallman et la FSF sont toujours détachés dans les affaires de licence et juridiques.
- Comité industriel du CCG: Il gère les affaires communautaires du CCG, les sujets de développement du CCG indépendants de la technologie, ainsi que la nomination et l’annonce des réviseurs et des mainteneurs. Il compte actuellement 13 membres.
- Mainteneurs mondiaux : Ils dominent les activités de développement du CCG. Dans une certaine mesure, ils déterminent la tendance de développement du CCG. Actuellement, il y a 13 mainteneurs mondiaux, qui n’occupent pas tous des postes au sein du Comité industriel du CCG.
- Mainteneurs Frontend, middle-end et backend : Ce sont les mainteneurs de frontend, backend et d’autres modules. Ils sont responsables du code du module GCC correspondant, et beaucoup d’entre eux sont les principaux contributeurs au code du module. Il convient de noter que les examinateurs sont généralement classés dans ce groupe. La différence est que les réviseurs ne peuvent pas approuver leur propre correctif, tandis que les mainteneurs peuvent soumettre leurs propres modifications dans le cadre de leur responsabilité sans l’approbation des réviseurs.
- Contributeurs : Ce sont les groupes de développeurs les plus étendus de la communauté GCC. Après avoir signé l’accord de copyright, tous les développeurs peuvent demander l’autorisation d’écriture après approbation de la communauté, puis soumettre le code par eux-mêmes.
Comme d’autres communautés open source, la communauté mature du CCG n’est plus dominée par les pirates informatiques. Les entreprises commerciales ont commencé à jouer un rôle important dans la communauté, telles que le recrutement de développeurs et le parrainage de réunions de développement. Actuellement, la communauté GCC est dominée par les types de sociétés commerciales suivants:
- Fournisseurs de systèmes, notamment RedHat et SUSE.
- Fournisseurs de puces, notamment Intel, ARM, AMD et IBM (PowerPC).
- Fournisseurs spécialisés, tels que CodeSourcery et fournisseurs de services de chaîne d’outils comme AdaCore basés sur le langage Ada. CodeSourcery a eu une brillante histoire et a recruté de nombreux développeurs célèbres, mais a décliné après son acquisition par Mentor.
Dans la communauté GCC actuelle, les fournisseurs de puces dominent le développement backend, tandis que les fournisseurs de systèmes guident d’autres domaines de développement. En termes de développement communautaire, le code GCC est actuellement hébergé sur son propre serveur SVN. Une API Git est fournie pour faciliter le développement et la soumission. L’examen des correctifs est similaire à celui de la communauté du noyau Linux et utilise le formulaire de liste de diffusion. Comme mentionné ci-dessus, la communauté du CCG est une société de connaissance relativement stable (ou fermée). La communauté compte essentiellement 150 à 200 contributeurs actifs chaque année et organise une conférence des développeurs en septembre de chaque année. En septembre 2019, la conférence des développeurs aura lieu à Montréal, au Canada.
Communauté LLVM
La communauté LLVM est une communauté de compilateurs conviviale pour noob. Il répond rapidement aux questions des nouveaux utilisateurs et aux critiques de correctifs. C’est également la base et la source des discussions ultérieures de la Fondation LLVM et de l’adoption du Code de conduite de la Communauté LLVM, et provoque une série de discussions politiquement correctes.
Tous les projets et problèmes LLVM sont discutés via la liste de diffusion DevExpress, et la soumission de code est notifiée via la liste de diffusion des validations. Tous les bogues et modifications des fonctionnalités sont suivis dans la liste des bogues. Les correctifs soumis sont recommandés pour les branches principales. Le style est conforme aux normes de codage LLVM et la révision du code est effectuée via Phabricator. Actuellement, le référentiel de code LLVM a été migré vers GitHub.
Contrairement à la communauté GCC, la communauté LLVM n’a que la Fondation LLVM. La Fondation LLVM compte huit membres. En plus de gérer les affaires communautaires de LLVM, chaque membre de la Fondation LLVM doit guider les questions de développement de LLVM liées à la technologie. Actuellement, la présidente est Tanya Lattner, l’épouse de Chris Lattner. Chris Lattner lui-même est également membre de la fondation et contrôle fortement la communauté LLVM et la direction du développement de LLVM.
La politique de révision du code dans la communauté LLVM est fondamentalement la même que celle de la communauté GCC. La différence est que, en raison du développement rapide de LLVM, de nombreux contributeurs n’ont pas d’autorisation d’accès commit et doivent soumettre leur code via les mainteneurs. Actuellement, les communautés Clang et LLVM comptent plus de 1 000 contributeurs chaque année. Généralement, les conférences de développeurs ont lieu en avril et en octobre chaque année. La conférence des développeurs en octobre 2019 se tiendra à San Jose, aux États-Unis.
La licence LLVM passe de la licence UIUC à la licence Apache 2.0 avec des exceptions LLVM. Il est principalement utilisé pour résoudre le problème que la bibliothèque d’exécution LLVM est basée sur une licence MIT et que l’autorisation de brevet requise pour le projet est trop étendue. En vertu de cette licence, LLVM permet à quiconque de dériver des produits commerciaux de LLVM sans aucune restriction, et n’exige pas que les dérivés fournissent du code source ouvert, favorisant ainsi l’utilisation étendue de LLVM, y compris:
- Le téléchargement ou l’utilisation de LLVM en tout ou en partie à des fins personnelles, internes ou commerciales. La possibilité de modifier le code LLVM sans le contribuer au projet.
- La création d’un paquet ou d’une version contenant LLVM. L’association de LLVM avec le code autorisé par toutes les autres licences open source majeures (y compris BSD, MIT, GPLv2 et GPLv3).
- Lorsque vous distribuez à nouveau LLVM, vous devez conserver l’avis de copyright. Vous ne pouvez pas supprimer ou remplacer l’en-tête de copyright. Le fichier binaire contenant LLVM doit contenir l’avis de copyright.
Comparaison des performances entre GCC et LLVM
Architecture: x86_64
Processeur: Processeur Intel (R) Xeon (R) Platinum 8163 à 2,50 GHz
Cache de données L1: 32 Ko
Cache L2: 1 024 Ko
Cache L3: 33 792 Ko
Mémoire: 800 Go
Système d’exploitation: Alibaba Group Enterprise Linux Server release 7.2 ( Paladin)
Noyau : 4.9.151–015.ali3000.alios7.x86_64
Compilateur: Clang/LLVM 8.0 GCC8.3.1
Benchmark
SPEC CPU 2017 est un ensemble d’outils de test de sous-système CPU pour tester le processeur, le cache, la mémoire et le compilateur. Il contient 43 tests de quatre catégories, y compris SPECspeed 2017 INT et FP qui testent la vitesse entière et la vitesse de fonctionnement en virgule flottante et SPECrate 2017 INT et FP qui testent le taux de concurrence entier et le taux de concurrence en virgule flottante. Clang ne supporte pas le langage Fortran. Par conséquent, dans cet exemple, les programmes C / C ++ de l’ensemble de tests de vitesse SPEC sont utilisés pour tester la différence de performance monocœur entre les programmes binaires générés par Clang et GCC. Le tableau suivant répertorie les ensembles SPEC CPU2017 C et C++ :
CINT2017 SpeedCFP2017 Speed600.perlbench_s619.lbm_s602.gcc_s644.nab_s605.mcf_s620.omnetpp_s623.xalancbmk_s625.x264_s631.jeng_s641.leela_s657.xz_s
Méthodes de test
Le framework d’automatisation LLVM-lnt est utilisé pour effectuer le test et comparer les performances. Il fonctionne de la même manière que runcpu du processeur SPEC. Avant l’exécution de LLVM-lnt, le cache (echo 3 >/proc/sys/vm/drop_caches) est effacé, puis l’ensemble de données de test s’exécute. Ensuite, l’ensemble de données ref s’exécute trois fois. La valeur moyenne des trois résultats du test ref est utilisée comme résultat final. Pour réduire les fluctuations de performances causées par la migration du processeur ou le changement de contexte, les processus s’exécutant sur l’ensemble de données de test et l’ensemble de données de référence sont liés à un cœur de PROCESSEUR à l’aide de l’outil d’affinité du processeur. Pour le test de compilation, cette méthode utilise le thread 1 pour construire le programme de test et comparer les éléments de test compilés depuis longtemps. Le temps de compilation n’inclut pas le temps d’exécution de l’éditeur de liens. Il inclut uniquement le moment où tous les fichiers source de tous les programmes de test sont générés.
Comparaison des performances de compilation
Le processus de compilation de GCC est le suivant: lisez le fichier source, prétraitez le fichier source, convertissez-le en IR, optimisez et générez un fichier d’assemblage. Ensuite, l’assembleur génère un fichier objet. Clang et LLVM ne s’appuient pas sur des compilateurs indépendants, mais intègrent des compilateurs auto-implémentés en backend. Le processus de génération de fichiers d’assemblage est omis dans le processus de génération de fichiers d’objets. Le fichier objet est généré directement à partir de l’IR. En outre, par rapport à l’IR GCC, la structure de données de l’IR LLVM est plus concise. Il occupe moins de mémoire pendant la compilation et prend en charge une traversée plus rapide. Par conséquent, Clang et LLVM sont avantageux en termes de temps de compilation, ce qui est prouvé par les données obtenues à partir de la compilation des spécifications, comme le montre la figure ci-dessous. Clang réduit le temps de compilation d’un seul thread de 5% à 10% par rapport à GCC. Par conséquent, Clang offre plus d’avantages pour la construction de grands projets.
Comparaison du temps de compilation des spécifications
Comparaison des performances d’exécution
La plupart des charges de travail cloud nécessitent que les applications puissent s’exécuter dans différents clusters. Lors de la création de ces applications, ne spécifiez pas de paramètres liés à la machine. Pour s’adapter à l’itération rapide causée par les changements de demande, les charges de travail hors site doivent également être déboguables. Par conséquent, en dehors de certaines bibliothèques stables et courantes qui permettent des niveaux d’optimisation de compilation élevés, la charge de travail elle-même a un niveau de compilation et d’optimisation faible (O2 ou inférieur). Pour répondre à cette exigence, ce document compare les performances de différents compilateurs aux niveaux d’optimisation O2 et O3 pour les programmes de vitesse INT, comme indiqué dans la figure suivante:
comparaison des performances de la vitesse INT SPEC CPU2017
GCC a un avantage de performance de 1% à 4% par rapport à Clang et LLVM pour la plupart des programmes aux niveaux O2 et O3, et a en moyenne un avantage de performance d’environ 3% pour la vitesse INT SPEC CPU2017. En termes de 600.perlbench_s et 602.gcc_s/O2, GCC a un grand avantage de performance (plus de 10%). Ces deux éléments de test n’ont pas de points chauds en suspens et peuvent refléter l’effet d’optimisation complet du compilateur. Les résultats des tests montrent que GCC est toujours avantageux dans l’optimisation des performances. Cependant, pour deux programmes liés à l’IA, dont 631.deepsjeng_s et 641.leela_s, qui sont nouvellement ajoutés au test de spécification, Clang et LLVM améliorent les performances de plus de 3% par rapport à GCC. Cela reflète également les progrès rapides de LLVM en termes d’optimisation. Pour le 625. optimisation x264_s O2, LLVM améliore les performances de 40% car le hotspot du cas est conforme aux règles vectorisées. Mais Clang et LLVM optimisent les vecteurs au niveau O2, tandis que GCC optimise les vecteurs au niveau O3. À l’exception des programmes vectorisés, GCC n’améliore pas considérablement les performances au niveau O3 par rapport à celles au niveau O2. En d’autres termes, les programmes ne sont pas sensibles à l’optimisation O3 de GCC. En revanche, Clang et LLVM améliorent considérablement les performances de certains programmes (tels que 600. perlbench_s et 602. gcc_s) au niveau O3.
Les programmes HPC, tels que FP Speed, fonctionnent généralement sur des serveurs haut de gamme. Ils ont des algorithmes de base stables, des exigences élevées en matière de vectorisation et de parallélisme liés aux performances, et permettent des niveaux élevés d’optimisation (O3 ou supérieur). Par conséquent, ce document compare les performances au niveau d’optimisation O3 + march= native (skylake-avx512), comme indiqué ci-dessous:
Comparaison des performances de SPEC CPU2017 FP Speed
Pour les deux programmes FP, GCC peut également améliorer les performances d’environ 3%. Clang et LLVM sont conservateurs dans l’optimisation des boucles et donc pas avantageux dans les performances. Cependant, le sous-projet Polly de Clang et LLVM fournit un optimiseur de boucle et de localité de données de haut niveau qui a été largement appliqué à l’apprentissage automatique, au calcul haute performance et à l’optimisation du calcul hétérogène. Je pense que Polly peut grandement améliorer les performances des programmes contenant des boucles hotspot conformes aux règles de vectorisation et de parallélisme. Je vais également analyser les performances de Polly dans une série de benchmarks et de charges de travail.
Remarques finales
D’après les tests de benchmarking ci-dessus, nous pouvons voir que Clang offre plus d’avantages pour la construction de grands projets tandis que GCC est toujours avantageux dans l’optimisation des performances. Le bla dépend de votre application spécifique
En plus de la comparaison des performances, je voudrais partager les avantages et les inconvénients de GCC et Clang et LLVM:
Avantages de GCC
- GCC prend en charge des langages plus traditionnels que Clang et LLVM, tels que Ada, Fortran et Go.
- GCC prend en charge plus d’architectures moins populaires et prend en charge RISC-V plus tôt que Clang et LLVM.
- GCC prend en charge plus d’extensions de langage et plus de fonctionnalités de langage d’assemblage que Clang et LLVM. GCC est toujours la seule option pour compiler le noyau Linux. Bien que des recherches sur la compilation du noyau en utilisant Clang et LLVM soient également signalées dans l’industrie, le noyau ne peut pas être compilé sans modifier le code source et les paramètres de compilation.
Les avantages de Clang et LLVM
- Les langages émergents utilisent les frameworks LLVM, tels que Swift, Rust, Julia et Ruby.
- Clang et LLVM sont conformes aux normes C et C ++ plus strictement que GCC. GNU Inline et d’autres problèmes lors de la mise à niveau de GCC ne se produisent pas.
- Clang prend également en charge certaines extensions, telles que les attributs pour la vérification de la sécurité des threads.
- Clang fournit des outils utiles supplémentaires, tels que scan-build et clang static analyzer pour l’analyse statique, clang-format et clang-tidy pour l’analyse syntaxique, ainsi que le plug-in d’éditeur Clangd.
- Clang fournit des informations de diagnostic plus précises et plus conviviales, et met en évidence les messages d’erreur, les lignes d’erreur, les invites de ligne d’erreur et les suggestions de réparation. Clang considère les informations de diagnostic comme une fonctionnalité. Les informations diagnostiques n’ont commencé à être améliorées qu’à partir de GCC 5.0 et sont devenues matures dans GCC 8.
(Article original de Ma Jun马骏)