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

  • _WIN32 ou _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