Detectando arquitetura de CPU tempo de compilação
-
02-07-2019 - |
Pergunta
O que é a maneira mais confiável para descobrir a arquitetura CPU quando compilar código C ou C ++? Tanto quanto eu posso dizer, compiladores diferentes têm seu próprio conjunto de definições pré-processador não-padrão (_M_X86
em MSVS, __i386__
, __arm__
no GCC, etc).
Existe um padrão maneira de detectar a arquitetura estou construindo para? Se não, há uma fonte para uma lista abrangente de tais definições para vários compiladores, como um cabeçalho com todos os #ifdef
s clichê?
Solução
Aqui estão algumas informações sobre pré-definido Architecture Macros e outros tipos de pre macros -definida.
Esta questão pergunta onde eles são definidos no código fonte GCC.
Outras dicas
Não há um padrão inter-compilador, mas cada um compilador tende a ser bastante consistente. Você pode construir um cabeçalho para si mesmo que é algo como isto:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
Não há muito ponto para uma lista abrangente, porque há milhares de compiladores, mas apenas 3-4 em uso generalizado (Microsoft C ++, GCC, Intel CC, talvez TenDRA?). Basta decidir que compiladores sua aplicação vai apoiar, lista seus #defines, e atualizar seu cabeçalho, conforme necessário.
Se você gostaria de despejar todos os recursos disponíveis em uma plataforma particular, você pode executar GCC como:
gcc -march=native -dM -E - </dev/null
Seria despejar macros como #define __SSE3__ 1
, #define __AES__ 1
, etc.
Se você quer uma solução cross-compiler então é só usar Boost.Predef
que contém
-
BOOST_ARCH_
para a arquitetura do sistema / CPU se está compilando para. -
BOOST_COMP_
para o compilador está usando. -
BOOST_LANG_
para os padrões de linguagem se está compilando contra. -
BOOST_LIB_C_
e BOOST_LIB_STD_ para a biblioteca padrão do C e C ++ em uso. -
BOOST_OS_
para o sistema operacional que está compilando a. -
BOOST_PLAT_
para plataformas em cima do sistema ou compiladores funcionamento. -
BOOST_ENDIAN_
para endianness da combinação OS e arquitetura. -
BOOST_HW_
para hardware específico apresenta. -
BOOST_HW_SIMD
para SIMD (Instrução múltipla Único de Dados) de detecção.
Por exemplo
#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
Você pode descobrir mais sobre como usá-lo aqui
Não há padrão nada. Brian gancho documentado um grupo destes em seu "portátil Open Source Harness", e ainda tenta transformá-los em algo coerente e utilizável (ymmv sobre isso). Veja o cabeçalho posh.h neste site:
Note, no link acima pode exigir que você insira algumas falso ID do usuário / senha devido a um ataque DoS há algum tempo.
Se você precisar de uma detecção de grão fino de recursos da CPU, a melhor abordagem é enviar também um programa de CPUID que saídas para stdout ou algum arquivo "cpu_config.h" o conjunto de características apoiada pela CPU. Então você integrar esse programa com o seu processo de criação.