Impact des compilateurs sur les architectures CPU x86/x64
Publié le 28/02/2012 par Guillaume Louel
C, C++, rôle du compilateurPour cet article, nous nous sommes intéressés plus particulièrement aux compilateurs C/C++. Développés respectivement à la fin des années 60 et 70, C et C++ sont des langages de programmation extrêmement populaires conçus à l'origine pour Unix. Ils sont utilisés majoritairement encore aujourd'hui pour la conception d'applications sous Windows. C est le plus ancien, il s'agit d'un langage dit procédural - à base de fonctions - tandis que C++ aura apporté entre autre la notion d'orientation objet (ou de multi paradigme pour les puristes).
Si C continue à être très populaire sous Unix et ses dérivés (Linux ou MacOS via Objective-C), sous Windows c'est généralement C++ qui a la primeur, Microsoft ayant favorisé C++ dans ses API depuis les années 90 (comme par exemple MFC, l'une des bibliothèques qui permet de concevoir les interfaces graphiques des applications Windows). Ces deux langages ayant une parenté commune (C++ ayant été développé comme une extension de C à l'origine, même si au fil des années les langages ont divergés), les compilateurs sont généralement communs entre les deux langages.
Interprété, compilé, à la voléeContrairement à des langages simplifiés comme le BASIC ou un interpréteur va lire, ligne à ligne, votre programme pour l'interpréter et le traduire dans un code lisible par le processeur, C et C++ se classent dans la catégorie des langages compilés. Les développeurs écrivent leurs logiciels dans ces langages puis lancent l'opération de compilation. Le but de la compilation étant de traduire le programme C/C++, relativement lisible, en code exécutable directement par le processeur (langage machine). Cette particularité permet à C/C++ d'être des langages (relativement) portables, on peut ainsi compiler un programme pour différents types d'architectures (ARM, PowerPC, ou x86 par exemple). Dans une architecture donnée, on pourra aussi réaliser des compilations optimisées pour certaines variantes, comme par exemple des versions 32 bits et 64 bits de son application, ou bien des versions spécifiques pour une architecture donnée (version d'une application nécessitant SSE2 par exemple). A moins donc d'avoir accès au code source du programme et à un compilateur, on doit donc subir les optimisations et les choix effectués par les développeurs, ce qui est l'une des raisons de ce dossier.
Un extrait de code C. main indique la fonction d'où débute le programme.
Car en effet même pour un "standard" donnée comme le x86, toutes les puces ne sont pas égales. Si les processeurs AMD et Intel - à génération équivalente - sont capables de faire tourner les mêmes instructions machines, les ingénieurs d'AMD et d'Intel peuvent avoir privilégié certaines instructions face à d'autres. La division peut par exemple être plus rapide sur un processeur qu'un autre. La compilation, à la manière de la traduction d'une langue à l'autre, n'est en effet pas une science exacte : on peut compiler un même programme de manières différentes. Si les programmes finaux effectueront le même travail (sauf erreur de compilation), leur code en langage machine sera différent. Le fait que x86 soit une architecture processeur qui comporte un très grand nombre d'instructions (une ISA CISC, à contrario des ISA RISC dont le jeu d'instruction est volontairement réduit) donne une marge assez large, x86 comportant de nos jours, avec les diverses extensions (MMX, SSE, etc) plus d'un millier d'instructions . La manière dont un compilateur fonctionne semble donc théoriquement très importante sur les performances finales, et on ne sera pas surpris de voir que et AMD et Intel non seulement participent activement au développement des compilateurs existants (que ce soit celui inclut dans Visual Studio de Microsoft, ou l'open source GCC) mais proposent également leurs propres compilateurs.
Il est à noter que depuis quelques années la problématique commence à changer avec des langages comme Java/JVM et C#/.NET. Développés respectivement par Sun et Microsoft, ces langages assez populaires dans les applications d'entreprise (mais ayant une traction plus limitée dans les applications grand public, même si par exemple les panneaux de contrôle graphiques d'AMD et d'Intel sont réalisés en C#/.NET) ont la particularité d'être compilés pour ce que l'on appelle une machine virtuelle. Il s'agit en effet d'un mix entre les concepts de langages interprétés et compilés : avec Java ou C#, le programme est compilé dans un langage intermédiaire, celui de la machine virtuelle (JVM/.NET). Au lancement, la machine virtuelle effectuera une compilation finale du programme, directement adaptée à la machine sur laquelle elle tourne (on parle de compilation JIT, Just In Time, ou à la volée). L'intérêt de la machine virtuelle est assez facile à comprendre, on peut ainsi supporter facilement plusieurs ISA et/ou plusieurs systèmes d'exploitations, c'est l'un des arguments qui a porté Java par exemple.
Pour ce qu'il s'agit des optimisations qui pourraient favoriser ou non une marque de processeur, la situation change : c'est celui qui contrôle la VM qui contrôle les optimisations qui seront incluses, ou pas. Notez enfin que si C/C++ sont principalement compilés, il est possible (avec quelques restrictions) d'utiliser C++ avec .NET. A l'inverse, C/C++ peuvent être également compilés à la volée via une plateforme open source comme Clang/LLVM . Seul défaut de la solution, elle est aujourd'hui très mal supportée sous Windows puisqu'elle ne supporte pas certaines extensions "Microsoft" au langage C/C++.
En effet, si C et C++ sont des langages standardisés, leur implémentation peut varier d'un compilateur à l'autre. D'une parce qu'il existe plusieurs versions des standards (versions ANSI, ISO, C9, C11 rien que pour le C) mais aussi car ils sont ouverts à de nombreuses extensions. Pire, certains compilateurs n'implémentent que partiellement les normes établies, ce qui est notoirement le cas des outils de Microsoft. Compiler un même programme sous trois environnements différents est un challenge !
Introduction
Optimisations et performances
Sommaire
Vos réactions
Contenus relatifs
- [+] 09/05: AMD Ryzen 7 2700, Ryzen 5 2600 et I...
- [+] 04/05: Un Coffee Lake 8 coeurs en préparat...
- [+] 27/04: Le 10nm d'Intel (encore) retardé, l...
- [+] 27/04: AMD Vega 7nm en labo, Zen 2 échanti...
- [+] 26/04: Jim Keller rejoint... Intel !
- [+] 23/04: MAJ de notre test des Ryzen 7 2700X...
- [+] 19/04: AMD Ryzen 2700X et 2600X : Les même...
- [+] 19/04: 2008-2018 : tests de 62 processeurs...
- [+] 18/04: ASUS AREZ, l'effet GeForce Partner ...
- [+] 13/04: Les AMD Ryzen Pinnacle Ridge en pré...