检测CPU架构编译时

时间:2008-09-30 06:57:53

标签: c++ c detection cpu-architecture compile-time

在编译C或C ++代码时,找出CPU架构最可靠的方法是什么?据我所知,不同的编译器有自己的一套非标准预处理器定义(MSVS中为_M_X86,GCC中为__i386____arm__等。)

是否有标准方法来检测我正在构建的架构?如果没有,是否有各种编译器的此类定义的综合列表的来源,例如包含所有样板#ifdef的标题?

7 个答案:

答案 0 :(得分:73)

以下是有关Pre-defined Architecture Macros和其他类型的预定义宏的一些信息。

GCC源代码中的这个问题asks where they are defined

答案 1 :(得分:14)

没有编译器间标准,但每个编译器都趋于一致。您可以为自己构建一个标题,如下所示:

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

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

没有太多指向全面的列表,因为有数千个编译器,但只有3-4个被广泛使用(Microsoft C ++,GCC,Intel CC,可能是TenDRA?)。只需确定您的应用程序将支持哪些编译器,列出他们的#defines,并根据需要更新您的标头。

答案 2 :(得分:5)

如果要在特定平台上转储所有可用功能,可以运行GCC,如:

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

它会转储像#define __SSE3__ 1#define __AES__ 1

这样的宏

答案 3 :(得分:4)

如果您要使用交叉编译器解决方案,则只需使用Boost.Predef,其中包含

  • BOOST_ARCH_用于系统/ CPU体系结构之一。
  • BOOST_COMP_用于正在使用的编译器。
  • BOOST_LANG_是一种针对的语言标准。
  • BOOST_LIB_C_和BOOST_LIB_STD_用于正在使用的C和C ++标准库。
  • BOOST_OS_用于我们要编译的操作系统。
  • BOOST_PLAT_(用于操作系统或编译器之上的平台)。
  • BOOST_ENDIAN_了解操作系统和体系结构组合的字节顺序。
  • BOOST_HW_了解特定于硬件的功能。
  • BOOST_HW_SIMD用于SIMD(单指令多数据)检测。

例如

#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

您可以找到有关如何使用它的更多信息here

答案 4 :(得分:3)

没有什么标准。 Brian Hook在他的“便携式开源线束”中记录了其中的一些,甚至试图将它们变成连贯可用的东西(ymmv就此而言)。请参阅本网站上的posh.h标题:

注意,上面的链接可能要求您在一段时间之前因DOS攻击而输入一些伪造的用户ID /密码。

答案 5 :(得分:2)

享受吧,我是本文的原作者。

extern "C" {
    const char *getBuild() { //Get current architecture, detectx nearly every architecture. Coded by Freak
        #if defined(__x86_64__) || defined(_M_X64)
        return "x86_64";
        #elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
        return "x86_32";
        #elif defined(__ARM_ARCH_2__)
        return "ARM2";
        #elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
        return "ARM3";
        #elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
        return "ARM4T";
        #elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
        return "ARM5"
        #elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
        return "ARM6T2";
        #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
        return "ARM6";
        #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
        return "ARM7";
        #elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
        return "ARM7A";
        #elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
        return "ARM7R";
        #elif defined(__ARM_ARCH_7M__)
        return "ARM7M";
        #elif defined(__ARM_ARCH_7S__)
        return "ARM7S";
        #elif defined(__aarch64__) || defined(_M_ARM64)
        return "ARM64";
        #elif defined(mips) || defined(__mips__) || defined(__mips)
        return "MIPS";
        #elif defined(__sh__)
        return "SUPERH";
        #elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
        return "POWERPC";
        #elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64)
        return "POWERPC64";
        #elif defined(__sparc__) || defined(__sparc)
        return "SPARC";
        #elif defined(__m68k__)
        return "M68K";
        #else
        return "UNKNOWN";
        #endif
    }
}

答案 6 :(得分:-2)

如果您需要对CPU功能进行细粒度检测,最好的方法是发送一个CPUID程序,该程序将输出到stdout或某些“cpu_config.h”文件的CPU支持的功能集。然后,将该程序与构建过程集成。