Detectando la arquitectura de la CPU en tiempo de compilación

81

¿Cuál es la forma más confiable de averiguar la arquitectura de la CPU al compilar código C o C ++? Por lo que puedo decir, los diferentes compiladores tienen su propio conjunto de definiciones de preprocesador no estándar ( _M_X86en MSVS __i386__, __arm__en GCC, etc.).

¿Existe una forma estándar de detectar la arquitectura para la que estoy construyendo? Si no es así, ¿hay una fuente para una lista completa de tales definiciones para varios compiladores, como un encabezado con todos los códigos estándar #ifdef?

Alex B
fuente
1
Básicamente, la misma respuesta para la detección del sistema operativo: stackoverflow.com/questions/142508/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

78

A continuación, se ofrece información sobre macros de arquitectura predefinidas y otros tipos de macros predefinidas.

Esta pregunta pregunta dónde se definen en el código fuente de GCC.

Sarga
fuente
¿El estándar C o C ++ define macros sugerentes para ser utilizadas por diferentes compiladores?
Krishna Oza
Esto parece correcto, pero ¿alguien puede citar el documento de GCC que dice que lo usa?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
15

No existe un estándar entre compiladores, pero cada compilador tiende a ser bastante consistente. Puede crear un encabezado para usted que sea algo como esto:

#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif

#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif

No tiene mucho sentido una lista completa, porque hay miles de compiladores pero solo 3-4 de uso generalizado (Microsoft C ++, GCC, Intel CC, ¿tal vez TenDRA?). Simplemente decida qué compiladores admitirá su aplicación, enumere sus #defines y actualice su encabezado según sea necesario.

John Millikin
fuente
4
Esto no funcionó para mí en Visual Studio 2010. _M_X86No se definió positivamente (compilación de 32 bits). El correcto es _M_IX86(crédito al enlace de Serge arriba).
Thomas
6

Si desea volcar todas las funciones disponibles en una plataforma en particular, puede ejecutar GCC como:

gcc -march=native -dM -E - </dev/null

Sería volcar macros como #define __SSE3__ 1, #define __AES__ 1, etc.

Wei Shen
fuente
-march=nativefalla para ARM y MIPS para GCC 4.9 y por debajo.
jww
4

Si desea una solución de compilador cruzado, simplemente use la Boost.Predefque contiene

  • BOOST_ARCH_ para la arquitectura del sistema / CPU para la que se está compilando.
  • BOOST_COMP_ para el compilador que está usando.
  • BOOST_LANG_ para los estándares de lenguaje contra los que uno está compilando.
  • BOOST_LIB_C_ y BOOST_LIB_STD_ para la biblioteca estándar C y C ++ en uso.
  • BOOST_OS_ para el sistema operativo con el que estamos compilando.
  • BOOST_PLAT_ para plataformas sobre sistema operativo o compiladores.
  • BOOST_ENDIAN_ para la endianidad del sistema operativo y la combinación de arquitectura.
  • BOOST_HW_ para características específicas de hardware.
  • BOOST_HW_SIMD para la detección SIMD (Single Instruction Multiple Data).

Por ejemplo

#if defined(BOOST_ARCH_X86)
    #if BOOST_ARCH_X86_64
        std::cout << "x86_64 " << BOOST_ARCH_X86_64 << " \n";
    #elif BOOST_ARCH_X86_32
        std::cout << "x86 " << BOOST_ARCH_X86_32 << " \n";
    #endif
#elif defined(BOOST_ARCH_ARM)
    #if _M_ARM
        std::cout << "ARM " << _M_ARM << " \n";
    #elif _M_ARM64
        std::cout << "ARM64 " << _M_ARM64 << " \n";
    #endif
#endif

Puede encontrar más información sobre cómo usarlo aquí.

phuclv
fuente
3

No hay nada estándar. Brian Hook documentó un montón de estos en su "Arnés de código abierto portátil", e incluso intenta convertirlos en algo coherente y utilizable (ymmv con respecto a eso). Vea el encabezado posh.h en este sitio:

Tenga en cuenta que el enlace anterior puede requerir que ingrese un ID de usuario / contraseña falsos debido a un ataque de DOS hace algún tiempo.

Michael Burr
fuente
2
Dios, perdón por el enlace falso, debería ser hookatooka.com/poshlib que proporciona información sobre el ID de usuario / contraseña. Mi navegador debe tener "inicio de sesión automático" de alguna visita anterior a la página.
Michael Burr
2
También vale la pena señalar ... Los autores del sitio web declararon por qué agregaron una contraseña: "Pido disculpas por las molestias, pero debido a un inexplicable ataque DDoS en nuestro enlace directo anterior, tuvimos que crear esta página para ' buffer 'contra el DDoS ... " No estoy seguro de que sea justo penalizar a Michael por ello.
jww
-2

Si necesita una detección detallada de las características de la CPU, el mejor enfoque es enviar también un programa CPUID que envíe a stdout o algún archivo "cpu_config.h" el conjunto de características admitidas por la CPU. Luego integra ese programa con su proceso de construcción.

zvrba
fuente
3
No funcionará para la compilación cruzada. ¿Y cómo compila un programa cpuid a menos que sepa en qué máquina necesita ejecutarse?
jforberg