CPUID的内在函数如信息?

时间:2013-07-20 03:40:40

标签: c++ intrinsics cpuid

考虑到我用C ++编写代码,如果可能的话,我想使用类似内在函数的解决方案来阅读有关硬件的有用信息,我的顾虑/考虑因素是:

  • 我不太了解汇编,只是为了得到这种信息是一项相当大的投资(尽管它看起来像CPU只是翻转价值和阅读寄存器。)
  • asm(英特尔和AT& T)至少有两种流行的语法,所以它是碎片化的
  • 奇怪的是,Intrinsics今天比asm代码更受欢迎和支持
  • 现在我的雷达中的所有编译器都不支持内联asm,MSVC 64位是一个;我担心我会发现其他类似的缺陷,同时深入研究我必须使用的不同编译器的功能集。
  • 考虑到这个交易我认为对我来说更有效率,它应该比任何asm代码更容易。

我要回答的最后一个问题是:如何用内在函数做类似的事情?因为我根本没有找到除CPUID操作码以外的任何内容来获取这种信息。

5 个答案:

答案 0 :(得分:11)

在挖掘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下工作。

答案 1 :(得分:8)

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

请注意,当ecx的初始值很重要时,您必须使用__cpuid_count()而不是__cpuid(),例如使用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 :(得分:7)

诸如此类的内在函数通常也是特定于编译器的。

MS VC ++有__cpuid(以及__cpuidex)来生成CPUID操作码。

至少据我所知,gcc / g ++并没有提供相同的功能。内联汇编似乎是唯一可用的选项。

答案 3 :(得分:3)

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

据称GCC在内在性方面跟随英特尔,因此它应该在GCC下可用。我不清楚微软是否提供它,因为它们提供了大多数(但不是全部)英特尔内在函数。

我对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

答案 4 :(得分:1)

对于曾孙代,这是如何在Win7 x64上通过GCC获取CPU供应商名称的方法

    #include <cpuid.h>
    ...
    int eax, ebx, ecx, edx;
    char vendor[13];
    __cpuid(0, eax, ebx, ecx, edx);
    memcpy(vendor, &ebx, 4);
    memcpy(vendor + 4, &edx, 4);
    memcpy(vendor + 8, &ecx, 4);
    vendor[12] = '\0';
    printf("CPU: %s\n", vendor);