¿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_X86
en 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
?
c++
c
detection
cpu-architecture
compile-time
Alex B
fuente
fuente
Respuestas:
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.
fuente
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.
fuente
_M_X86
No se definió positivamente (compilación de 32 bits). El correcto es_M_IX86
(crédito al enlace de Serge arriba).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.fuente
-march=native
falla para ARM y MIPS para GCC 4.9 y por debajo.Si desea una solución de compilador cruzado, simplemente use la
Boost.Predef
que contieneBOOST_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í.
fuente
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.
fuente
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.
fuente