2013-07-20 34 views
14

考虑到我编码C++,如果可能的话,我想用一个内部函数样的解决方案,以了解硬件的有用信息,我关注/注意事项有:CPUID的内部信息如信息?

  • 我不知道组装那么获得这种信息将会是相当大的投资(尽管它看起来像CPU,它只是翻转数值和读取寄存器)。
  • 至少有2种流行的asm语法(Intel和AT & T) ,所以它支离破碎
  • 奇怪的是,这些天,内向函数比asm代码更受欢迎和支持
  • 并非我所有的编译器现在支持内联汇编,MSVC 64位是一个;恐怕我会在深入挖掘必须使用的不同编译器的功能集的同时发现其他类似的缺陷。
  • 考虑到我认为这对我来说在Intrinsics上下注更有效率的交易,它应该比任何asm代码更容易。

而我必须回答的最后一个问题是:如何用intrinsics做类似的事情?因为除了CPUID操作码以外我没有发现任何东西来获取这类信息。

+0

锵有一个集成的汇编,其对英特尔的风格装配支撑位在时间参差不齐。它不能在英特尔风格下生成一个简单的“negate(neg)”。 – jww

回答

10

经过一番挖掘I have found一个有用的内置函数,它是gcc特有的。

唯一的问题是,这种功能实在有限(基本上就只有2个功能,1为CPU“名”和1的组寄存器)

一个例子是

#include <stdio.h> 

int main() 
{ 
    if (__builtin_cpu_supports("mmx")) { 
     printf("\nI got MMX !\n"); 
    } else 
     printf("\nWhat ? MMX ? What is that ?\n"); 
    return (0); 
} 

显然这个内置函数也在mingw-w64下工作。

+0

从问题:*“并非所有的编译器...支持内联汇编,MSVC 64位是一个”*。提供的代码当然不适用于Microsoft编译器。在您拥有GCC和MS解决方案之前,您应该避免接受您的答案。 – jww

7

像这样的内在函数也通常是编译器特有的。

MS VC++有一个__cpuid(和一个__cpuidex)生成一个CPUID操作代码。

至少据我所知,gcc/g ++没有提供与此类似的东西。内联汇编似乎是唯一可用的选项。

+1

我发现了一些东西http://stackoverflow.com/a/17759098/2485710 – user2485710

+1

gcc提供了一个'cpuid.h'头文件,它提供了一个'__cpuid'宏(定义与MSVC不同,不介意)以及'__get_cpuid'功能。 – rdb

6

的gcc包括CPUID接口:

http://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/i386/cpuid.h

这些似乎并没有得到很好的记录,但例如使用可以在这里找到:

http://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=gcc/config/i386/driver-i386.c

注意,您必须使用__cpuid_count()而不是__cpuid()当ecx的初始值很重要时,例如使用avx/avx2检测。

正如user2485710指出的那样,gcc可以为您完成所有cpu功能检测工作。从gcc 4.8.1开始,__builtin_cpu_supports()支持的完整功能列表为:cmov,mmx,popcnt,sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx和avx2。

2

对于x86/x64,Intel提供了一个名为_may_i_use_cpu_feature的内部函数。您可以在Intel Intrinsics Guide页面的常规支持类别下找到它。以下是英特尔文档的翻版。

海湾合作委员会似乎跟随英特尔的内在关系,所以它应该可以在海湾合作委员会。我不清楚微软是否提供它,因为它们提供了大部分(但不是全部)的英特尔内核。

我不知道ARM的任何内容。据我所知,在ARM下没有__builtin_cpu_supports("neon"),__builtin_cpu_supports("crc32"),__builtin_cpu_supports("aes"),__builtin_cpu_supports("pmull"),__builtin_cpu_supports("sha")等。对于ARM,您必须执行CPU feature probing


Synopsis 

int _may_i_use_cpu_feature (unsigned __int64 a) 

#include "immintrin.h" 

Description 

Dynamically query the processor to determine if the processor-specific feature(s) specified 
in a are available, and return true or false (1 or 0) if the set of features is 
available. Multiple features may be OR'd together. This intrinsic does not check the 
processor vendor. See the valid feature flags below: 

Operation 

    _FEATURE_GENERIC_IA32 
    _FEATURE_FPU 
    _FEATURE_CMOV 
    _FEATURE_MMX 
    _FEATURE_FXSAVE 
    _FEATURE_SSE 
    _FEATURE_SSE2 
    _FEATURE_SSE3 
    _FEATURE_SSSE3 
    _FEATURE_SSE4_1 
    _FEATURE_SSE4_2 
    _FEATURE_MOVBE 
    _FEATURE_POPCNT 
    _FEATURE_PCLMULQDQ 
    _FEATURE_AES 
    _FEATURE_F16C 
    _FEATURE_AVX 
    _FEATURE_RDRND 
    _FEATURE_FMA 
    _FEATURE_BMI 
    _FEATURE_LZCNT 
    _FEATURE_HLE 
    _FEATURE_RTM 
    _FEATURE_AVX2 
    _FEATURE_KNCNI 
    _FEATURE_AVX512F 
    _FEATURE_ADX 
    _FEATURE_RDSEED 
    _FEATURE_AVX512ER 
    _FEATURE_AVX512PF 
    _FEATURE_AVX512CD 
    _FEATURE_SHA 
    _FEATURE_MPX