Domanda

Qual è il modo più affidabile per scoprire l'architettura della CPU durante la compilazione del codice C o C ++? Per quanto posso dire, diversi compilatori hanno il proprio set di definizioni di preprocessore non standard ( _M_X86 in MSVS, __i386__ , __arm__ in GCC , ecc.)

Esiste un modo standard per rilevare l'architettura per la quale sto costruendo? In caso contrario, esiste una fonte per un elenco completo di tali definizioni per vari compilatori, come un'intestazione con tutte le piastre di caldaia #ifdef s?

È stato utile?

Soluzione

Ecco alcune informazioni su Macro di architettura predefinite e altri tipi di pre macro definite.

Questa domanda chiede dove sono definiti nel codice sorgente GCC.

Altri suggerimenti

Non esiste uno standard inter-compilatore, ma ogni compilatore tende ad essere abbastanza coerente. Puoi creare un'intestazione per te che è qualcosa del genere:

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

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

Non ha molto senso un elenco completo, perché ci sono migliaia di compilatori ma solo 3-4 in uso diffuso (Microsoft C ++, GCC, Intel CC, forse TenDRA?). Decidi semplicemente quali compilatori saranno supportati dalla tua applicazione, elenca le loro #define e aggiorna l'intestazione secondo necessità.

Se desideri scaricare tutte le funzionalità disponibili su una particolare piattaforma, puoi eseguire GCC come:

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

Dump di macro come #define __SSE3__ 1 , #define __AES__ 1 , ecc.

Se desideri una soluzione di cross-compilatore, utilizza Boost.Predef che contiene

  • BOOST_ARCH_ per l'architettura di sistema / CPU per cui si sta compilando.
  • BOOST_COMP_ per il compilatore in uso.
  • BOOST_LANG_ per gli standard linguistici si sta compilando.
  • BOOST_LIB_C_ e BOOST_LIB_STD_ per la libreria standard C e C ++ in uso.
  • BOOST_OS_ per il sistema operativo che stiamo compilando.
  • BOOST_PLAT_ per piattaforme su sistema operativo o compilatori.
  • BOOST_ENDIAN_ per endianness della combinazione di sistema operativo e architettura.
  • BOOST_HW_ per funzionalità specifiche dell'hardware.
  • BOOST_HW_SIMD per rilevamento SIMD (Single Instruction Multiple Data).

Ad esempio

#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

Puoi scoprire di più su come usarlo qui

Non c'è nulla di standard. Brian Hook ha documentato alcuni di questi nel suo "cablaggio open source portatile", e persino cerca di trasformarli in qualcosa di coerente e utilizzabile (ymmv a riguardo). Vedi l'intestazione posh.h su questo sito:

Nota, il link sopra potrebbe richiedere di inserire un userid / password fasulli a causa di un attacco DOS qualche tempo fa.

Se hai bisogno di un rilevamento approfondito delle funzionalità della CPU, l'approccio migliore è spedire anche un programma CPUID che trasmetta a stdout o alcuni "cpu_config.h". archiviare il set di funzionalità supportate dalla CPU. Quindi integri quel programma con il tuo processo di generazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top