Pregunta

¿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 sé, diferentes compiladores tienen su propio conjunto de definiciones de preprocesador no estándar ( _M_X86 en MSVS, __i386__ , __arm__ en GCC , etc).

¿Hay 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 textos #ifdef s?

¿Fue útil?

Solución

Aquí hay información sobre macros de arquitectura predefinidas y otros tipos de pre -definidas macros.

Esta pregunta pregunta dónde están definidas en el código fuente de GCC.

Otros consejos

No hay un estándar inter-compilador, pero cada compilador tiende a ser bastante consistente. Puedes crear un encabezado para ti 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 son de uso generalizado (Microsoft C ++, GCC, Intel CC, ¿quizás TenDRA?). Simplemente decida qué compiladores admitirá su aplicación, haga una lista de sus #defines y actualice su encabezado según sea necesario.

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

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

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

Si desea una solución de compilación cruzada, use Boost.Predef que contiene

  • BOOST_ARCH_ para la arquitectura del sistema / CPU por la que se está compilando.
  • BOOST_COMP_ para el compilador que está utilizando.
  • BOOST_LANG_ para los estándares de idioma con los que se está compilando.
  • BOOST_LIB_C_ y BOOST_LIB_STD_ para la biblioteca estándar de C y C ++ en uso.
  • BOOST_OS_ para el sistema operativo que estamos compilando.
  • BOOST_PLAT_ para plataformas sobre el sistema operativo o compiladores.
  • BOOST_ENDIAN_ para la endianidad de la combinación de sistema operativo y arquitectura.
  • BOOST_HW_ para características específicas del hardware.
  • BOOST_HW_SIMD para la detección de SIMD (datos múltiples de instrucción única).

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í

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). Consulte el encabezado de posh.h en este sitio:

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

Si necesita una detección precisa de las características de la CPU, el mejor enfoque es enviar también un programa CPUID que salga a la salida estándar o algo de " cpu_config.h " Archivo del conjunto de características soportadas por la CPU. Luego integras ese programa con tu proceso de construcción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top