__cpuid, __cpuidex

来源:互联网 发布:炒股软件 知乎 编辑:程序博客网 时间:2024/06/06 03:16

https://msdn.microsoft.com/zh-cn/library/hskdteyh(v=vs.140).aspx

https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=ZH-CN&k=k(%22intrin%2F__cpuid%22);k(__cpuid);k(SolutionItemsProject);k(DevLang-C%2B%2B);k(TargetOS-Windows)&rd=true

Microsoft Specific

Generates the cpuid instruction that is available on x86 and x64. This instruction queries the processor for information about supported features and the CPU type.

void __cpuid(   int cpuInfo[4],   int function_id);void __cpuidex(   int cpuInfo[4],   int function_id,   int subfunction_id);

Parameters

[out] cpuInfo

An array of four integers that contains the information returned in EAX, EBX, ECX, and EDX about supported features of the CPU.

[in] function_id

A code that specifies the information to retrieve, passed in EAX.

[in] subfunction_id

An additional code that specifies information to retrieve, passed in ECX.

Requirements

Intrinsic

Architecture

__cpuid

x86, x64

__cpuidex

x86, x64

Header file <intrin.h>

Remarks

This intrinsic stores the supported features and CPU information returned by the cpuid instruction incpuInfo, an array of four 32-bit integers that is filled with the values of the EAX, EBX, ECX, and EDX registers (in that order). The information returned has a different meaning depending on the value passed as thefunction_id parameter. The information returned with various values of function_id is processor-dependent.

The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. The __cpuidex intrinsic sets the value of the ECX register to subfunction_id before it generates the cpuid instruction. This enables you to gather additional information about the processor.

For more information about the specific parameters to use and the values returned by these intrinsics on Intel processors, see the documentation for the cpuid instruction in Intel 64 and IA-32 Architectures Software Developers Manual Volume 2: Instruction Set Reference and Intel Architecture Instruction Set Extensions Programming Reference. Intel documentation uses the terms "leaf" and "subleaf" for thefunction_id and subfunction_id parameters passed in EAX and ECX.

For more information about the specific parameters to use and the values returned by these intrinsics on AMD processors, see the documentation for the cpuid instruction in AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions and in the Revision Guides for specific processor families. AMD documentation uses the terms "function number" and "subfunction number" for thefunction_id and subfunction_id parameters passed in EAX and ECX.

When the function_id argument is 0, cpuInfo[0] returns the highest available non-extended function_idsupported by the processor. The processor manufacturer is encoded in cpuInfo[1]cpuInfo[2], and cpuInfo[3].

Support for specific instruction set extensions and CPU features is encoded in the cpuInfo results returned for higher function_id values. For more information, see the manuals linked above, and the following example code.

Some processors support Extended Function CPUID information. If this is supported, function_id values from 0x80000000 might be used to return information. To determine the maximum meaningful value allowed, setfunction_id to 0x80000000. The maximum value of function_id supported for extended functions will be written to cpuInfo[0].

Example

This example shows some of the information available through the __cpuid and __cpuidex intrinsics. The app lists the instruction set extensions supported by the current processor. The output shows a possible result for a particular processor.

// InstructionSet.cpp // Compile by using: cl /EHsc /W4 InstructionSet.cpp// processor: x86, x64// Uses the __cpuid intrinsic to get information about // CPU extended instruction set support.#include <iostream>#include <vector>#include <bitset>#include <array>#include <string>#include <intrin.h>class InstructionSet{    // forward declarations    class InstructionSet_Internal;public:    // getters    static std::string Vendor(void) { return CPU_Rep.vendor_; }    static std::string Brand(void) { return CPU_Rep.brand_; }    static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }    static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }    static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }    static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }    static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }    static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }    static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }    static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; }    static bool MOVBE(void) { return CPU_Rep.f_1_ECX_[22]; }    static bool POPCNT(void) { return CPU_Rep.f_1_ECX_[23]; }    static bool AES(void) { return CPU_Rep.f_1_ECX_[25]; }    static bool XSAVE(void) { return CPU_Rep.f_1_ECX_[26]; }    static bool OSXSAVE(void) { return CPU_Rep.f_1_ECX_[27]; }    static bool AVX(void) { return CPU_Rep.f_1_ECX_[28]; }    static bool F16C(void) { return CPU_Rep.f_1_ECX_[29]; }    static bool RDRAND(void) { return CPU_Rep.f_1_ECX_[30]; }    static bool MSR(void) { return CPU_Rep.f_1_EDX_[5]; }    static bool CX8(void) { return CPU_Rep.f_1_EDX_[8]; }    static bool SEP(void) { return CPU_Rep.f_1_EDX_[11]; }    static bool CMOV(void) { return CPU_Rep.f_1_EDX_[15]; }    static bool CLFSH(void) { return CPU_Rep.f_1_EDX_[19]; }    static bool MMX(void) { return CPU_Rep.f_1_EDX_[23]; }    static bool FXSR(void) { return CPU_Rep.f_1_EDX_[24]; }    static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }    static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; }    static bool FSGSBASE(void) { return CPU_Rep.f_7_EBX_[0]; }    static bool BMI1(void) { return CPU_Rep.f_7_EBX_[3]; }    static bool HLE(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[4]; }    static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; }    static bool BMI2(void) { return CPU_Rep.f_7_EBX_[8]; }    static bool ERMS(void) { return CPU_Rep.f_7_EBX_[9]; }    static bool INVPCID(void) { return CPU_Rep.f_7_EBX_[10]; }    static bool RTM(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[11]; }    static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; }    static bool RDSEED(void) { return CPU_Rep.f_7_EBX_[18]; }    static bool ADX(void) { return CPU_Rep.f_7_EBX_[19]; }    static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }    static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }    static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }    static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; }    static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }    static bool LAHF(void) { return CPU_Rep.f_81_ECX_[0]; }    static bool LZCNT(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_ECX_[5]; }    static bool ABM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[5]; }    static bool SSE4a(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[6]; }    static bool XOP(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[11]; }    static bool TBM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[21]; }    static bool SYSCALL(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[11]; }    static bool MMXEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[22]; }    static bool RDTSCP(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[27]; }    static bool _3DNOWEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[30]; }    static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }private:    static const InstructionSet_Internal CPU_Rep;    class InstructionSet_Internal    {    public:        InstructionSet_Internal()            : nIds_{ 0 },            nExIds_{ 0 },            isIntel_{ false },            isAMD_{ false },            f_1_ECX_{ 0 },            f_1_EDX_{ 0 },            f_7_EBX_{ 0 },            f_7_ECX_{ 0 },            f_81_ECX_{ 0 },            f_81_EDX_{ 0 },            data_{},            extdata_{}        {            //int cpuInfo[4] = {-1};            std::array<int, 4> cpui;            // Calling __cpuid with 0x0 as the function_id argument            // gets the number of the highest valid function ID.            __cpuid(cpui.data(), 0);            nIds_ = cpui[0];            for (int i = 0; i <= nIds_; ++i)            {                __cpuidex(cpui.data(), i, 0);                data_.push_back(cpui);            }            // Capture vendor string            char vendor[0x20];            memset(vendor, 0, sizeof(vendor));            *reinterpret_cast<int*>(vendor) = data_[0][1];            *reinterpret_cast<int*>(vendor + 4) = data_[0][3];            *reinterpret_cast<int*>(vendor + 8) = data_[0][2];            vendor_ = vendor;            if (vendor_ == "GenuineIntel")            {                isIntel_ = true;            }            else if (vendor_ == "AuthenticAMD")            {                isAMD_ = true;            }            // load bitset with flags for function 0x00000001            if (nIds_ >= 1)            {                f_1_ECX_ = data_[1][2];                f_1_EDX_ = data_[1][3];            }            // load bitset with flags for function 0x00000007            if (nIds_ >= 7)            {                f_7_EBX_ = data_[7][1];                f_7_ECX_ = data_[7][2];            }            // Calling __cpuid with 0x80000000 as the function_id argument            // gets the number of the highest valid extended ID.            __cpuid(cpui.data(), 0x80000000);            nExIds_ = cpui[0];            char brand[0x40];            memset(brand, 0, sizeof(brand));            for (int i = 0x80000000; i <= nExIds_; ++i)            {                __cpuidex(cpui.data(), i, 0);                extdata_.push_back(cpui);            }            // load bitset with flags for function 0x80000001            if (nExIds_ >= 0x80000001)            {                f_81_ECX_ = extdata_[1][2];                f_81_EDX_ = extdata_[1][3];            }            // Interpret CPU brand string if reported            if (nExIds_ >= 0x80000004)            {                memcpy(brand, extdata_[2].data(), sizeof(cpui));                memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));                memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));                brand_ = brand;            }        };        int nIds_;        int nExIds_;        std::string vendor_;        std::string brand_;        bool isIntel_;        bool isAMD_;        std::bitset<32> f_1_ECX_;        std::bitset<32> f_1_EDX_;        std::bitset<32> f_7_EBX_;        std::bitset<32> f_7_ECX_;        std::bitset<32> f_81_ECX_;        std::bitset<32> f_81_EDX_;        std::vector<std::array<int, 4>> data_;        std::vector<std::array<int, 4>> extdata_;    };};// Initialize static member dataconst InstructionSet::InstructionSet_Internal InstructionSet::CPU_Rep;// Print out supported instruction set extensionsint main(){    auto& outstream = std::cout;    auto support_message = [&outstream](std::string isa_feature, bool is_supported) {        outstream << isa_feature << (is_supported ? " supported" : " not supported") << std::endl;    };    std::cout << InstructionSet::Vendor() << std::endl;    std::cout << InstructionSet::Brand() << std::endl;        support_message("3DNOW",       InstructionSet::_3DNOW());    support_message("3DNOWEXT",    InstructionSet::_3DNOWEXT());    support_message("ABM",         InstructionSet::ABM());    support_message("ADX",         InstructionSet::ADX());    support_message("AES",         InstructionSet::AES());    support_message("AVX",         InstructionSet::AVX());    support_message("AVX2",        InstructionSet::AVX2());    support_message("AVX512CD",    InstructionSet::AVX512CD());    support_message("AVX512ER",    InstructionSet::AVX512ER());    support_message("AVX512F",     InstructionSet::AVX512F());    support_message("AVX512PF",    InstructionSet::AVX512PF());    support_message("BMI1",        InstructionSet::BMI1());    support_message("BMI2",        InstructionSet::BMI2());    support_message("CLFSH",       InstructionSet::CLFSH());    support_message("CMPXCHG16B",  InstructionSet::CMPXCHG16B());    support_message("CX8",         InstructionSet::CX8());    support_message("ERMS",        InstructionSet::ERMS());    support_message("F16C",        InstructionSet::F16C());    support_message("FMA",         InstructionSet::FMA());    support_message("FSGSBASE",    InstructionSet::FSGSBASE());    support_message("FXSR",        InstructionSet::FXSR());    support_message("HLE",         InstructionSet::HLE());    support_message("INVPCID",     InstructionSet::INVPCID());    support_message("LAHF",        InstructionSet::LAHF());    support_message("LZCNT",       InstructionSet::LZCNT());    support_message("MMX",         InstructionSet::MMX());    support_message("MMXEXT",      InstructionSet::MMXEXT());    support_message("MONITOR",     InstructionSet::MONITOR());    support_message("MOVBE",       InstructionSet::MOVBE());    support_message("MSR",         InstructionSet::MSR());    support_message("OSXSAVE",     InstructionSet::OSXSAVE());    support_message("PCLMULQDQ",   InstructionSet::PCLMULQDQ());    support_message("POPCNT",      InstructionSet::POPCNT());    support_message("PREFETCHWT1", InstructionSet::PREFETCHWT1());    support_message("RDRAND",      InstructionSet::RDRAND());    support_message("RDSEED",      InstructionSet::RDSEED());    support_message("RDTSCP",      InstructionSet::RDTSCP());    support_message("RTM",         InstructionSet::RTM());    support_message("SEP",         InstructionSet::SEP());    support_message("SHA",         InstructionSet::SHA());    support_message("SSE",         InstructionSet::SSE());    support_message("SSE2",        InstructionSet::SSE2());    support_message("SSE3",        InstructionSet::SSE3());    support_message("SSE4.1",      InstructionSet::SSE41());    support_message("SSE4.2",      InstructionSet::SSE42());    support_message("SSE4a",       InstructionSet::SSE4a());    support_message("SSSE3",       InstructionSet::SSSE3());    support_message("SYSCALL",     InstructionSet::SYSCALL());    support_message("TBM",         InstructionSet::TBM());    support_message("XOP",         InstructionSet::XOP());    support_message("XSAVE",       InstructionSet::XSAVE());}
<span id="mt34" class="sentence" data-guid="f3565260-8763-d82d-bd8d-368d42b0f016" data-approved="" genuineintel"="" xml:space="preserve">GenuineIntel        Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz3DNOW not supported3DNOWEXT not supportedABM not supportedADX not supportedAES supportedAVX supportedAVX2 not supportedAVX512CD not supportedAVX512ER not supportedAVX512F not supportedAVX512PF not supportedBMI1 not supportedBMI2 not supportedCLFSH supportedCMPXCHG16B supportedCX8 supportedERMS not supportedF16C not supportedFMA not supportedFSGSBASE not supportedFXSR supportedHLE not supportedINVPCID not supportedLAHF supportedLZCNT not supportedMMX supportedMMXEXT not supportedMONITOR not supportedMOVBE not supportedMSR supportedOSXSAVE supportedPCLMULQDQ supportedPOPCNT supportedPREFETCHWT1 not supportedRDRAND not supportedRDSEED not supportedRDTSCP supportedRTM not supportedSEP supportedSHA not supportedSSE supportedSSE2 supportedSSE3 supportedSSE4.1 supportedSSE4.2 supportedSSE4a not supportedSSSE3 supportedSYSCALL supportedTBM not supportedXOP not supportedXSAVE supported

0 0
原创粉丝点击