Détecter la plateforme
Lorsque l'on souhaite optimiser son code, il est essentiel de connaître les spécificités de la plateforme pour laquelle on compile le programme. gcc propose des options lors de son invocation pour cibler une architecture particulière. De plus, le préprocesseur offre des macros permettant d'implémenter des versions de code spécifiques à la plateforme sur laquelle votre programme devra fonctionner.
Pourquoi détecter la plateforme cible ?
La détection de la plateforme cible permet d'exploiter au mieux les capacités du matériel, d'améliorer les performances et de garantir la compatibilité. Par exemple, certains processeurs peuvent avoir des jeux d'instructions spécifiques qui peuvent être utilisés pour accélérer certaines opérations.
Utiliser gcc pour cibler une architecture
gcc permet de spécifier l'architecture cible en utilisant l'option -march. Par exemple :
gcc -march=native -o mon_programme mon_programme.c
Cette commande compile mon_programme.c en utilisant les optimisations spécifiques à l'architecture du processeur de la machine de compilation.
Utiliser les macros du préprocesseur pour détecter la plateforme
Le préprocesseur C/C++ propose plusieurs macros prédéfinies pour détecter l'architecture et la plateforme. Voici un exemple :
#ifdef __x86_64__
// Code spécifique pour les architectures x86_64
#elif defined(__arm__)
// Code spécifique pour les architectures ARM
#else
// Code générique pour les autres architectures
#endif
Un large choix
Il existe de nombreux autres noms de plateformes (ou macros) pour détecter différentes architectures et environnements. Ces macros sont un bon moyen d'adapter votre code en fonction de l'architecture cible et du système d'exploitation, garantissant ainsi une meilleure compatibilité et des performances optimales. En voici quelques-unes des plus couramment utilisées :
Macros pour détecter les architectures processeur
__x86_64__: Pour les architectures x86_64 (AMD64 ou Intel 64)__i386__: Pour les architectures x86 32 bits (Intel 386 ou supérieur)__arm__: Pour les architectures ARM__aarch64__: Pour les architectures ARM 64 bits__powerpc__ou__powerpc64__: Pour les architectures PowerPC 32 bits ou 64 bits__mips__: Pour les architectures MIPS__riscv: Pour les architectures RISC-V
Macros pour détecter les systèmes d'exploitation
_WIN32ou_WIN64: Pour les systèmes Windows (32 bits ou 64 bits)__linux__: Pour les systèmes Linux__APPLE__et__MACH__: Pour les systèmes macOS__ANDROID__: Pour les systèmes Android__unix__: Pour les systèmes Unix en général
Exemples d'utilisation des macros
L'utilisation de ces macro est identique à l'exemple donné plus haut.
#if defined(__x86_64__)
// Code spécifique pour x86_64
#elif defined(__i386__)
// Code spécifique pour x86 32 bits
#elif defined(__arm__)
// Code spécifique pour ARM 32 bits
#elif defined(__aarch64__)
// Code spécifique pour ARM 64 bits
#elif defined(__powerpc__) || defined(__powerpc64__)
// Code spécifique pour PowerPC
#elif defined(__mips__)
// Code spécifique pour MIPS
#elif defined(__riscv)
// Code spécifique pour RISC-V
#endif