关于获取各种CPUID信息,我之前积累了不少代码,现在决定将它们封装在一个模块中,方便代码复用。 其次,前面只是介绍了CPUID的一些常用功能,而Intel、AMD的手册中定义了大量的CPUID功能。所以我希望有一个程序能按照功能号顺序,依次显示所有的CPUID信息。这样就能很方便的与Intel、AMD的手册进行对照,有助于学习与理解。
一、模块设计
最初方案是 想将所有功能全部放在一个“ccpuid.h”头文件中,这样用起来会比较方便。 但是考虑到全局变量等问题,以及需要编写CCPUID类。所以最终决定按照常规做法,分解为头文件与实现文件。
对于原先所写的宏定义、类型定义等声明性内容,可以直接放在头文件中。 对于原先的simd_sse_names等常数数组,考虑到全局变量问题,觉得作为CCPUID类的静态成员会比较好(CCPUID::SseNames、CCPUID::AvxNames)。 对于原先的函数,__cpuid/__cpuidex作为内联函数,放在头文件中;而其他函数作为普通函数,放在实现文件中。
除了封装原来的代码之外,还决定增加这些功能—— 1. 全部的CPUIDFIELD常数。根据Intel、AMD手册及网络上的一些资料,将目前所有的CPUIDFIELD常数均定义一遍,方便各种情况下的使用。 2. CPUID字段的描述信息。定义了CPUIDFIELDDESC结构体,然后还定义了CCPUID::CPUFDesc这个静态成员,它是CPUIDFIELDDESC结构体数组,记录了每条CPUIDFIELD常数的名称与描述文本。这样就可以通过查找表格得知CPUIDFIELD常数的描述信息。 3. 缓存的描述信息。这是为了方便使用CPUID指令的功能2是获取缓存信息。因为每一个字节代表不同的意义,所以可以使用一个256个项目的字符串指针数组来存储描述文本。(CCPUID::CacheDesc) 4. CCPUID类。拥有存储CPUID信息的能力,提供Vendor、mmx等方法,用于随时翻查CPUID信息。还设计一个cur静态方法,返回一个默认的CCPUID对象,简化代码编写。
二、测试程序
2.1 简单使用
最基本的用法是,定义一个CCPUID变量,然后调用RefreshAll方法刷新信息—— CCPUID ccid; ccid.RefreshAll();
在大多数时候,为了简化代码,可以调用cur静态方法来获得默认的CCPUID对象—— CCPUID& ccid = CCPUID::cur();
获得了CCPUID对象之后,便可以调用它的成员函数来获取基本信息——
printf("CCPUID.InfoCount:\t%d\n", ccid.InfoCount());
printf("CCPUID.LFuncStd:\t%.8Xh\n", ccid.LFuncStd());
printf("CCPUID.LFuncExt:\t%.8Xh\n", ccid.LFuncExt());
printf("CCPUID.Vendor:\t%s\n", ccid.Vendor());
//printf("CCPUID.Brand:\t%s\n", ccid.Brand());
printf("CCPUID.BrandTrim:\t%s\n", ccid.BrandTrim());
printf("CCPUID.InfoCount:\t%d\n", ccid.InfoCount());
printf("CCPUID.LFuncStd:\t%.8Xh\n", ccid.LFuncStd());
printf("CCPUID.LFuncExt:\t%.8Xh\n", ccid.LFuncExt());
printf("CCPUID.Vendor:\t%s\n", ccid.Vendor());
//printf("CCPUID.Brand:\t%s\n", ccid.Brand());
printf("CCPUID.BrandTrim:\t%s\n", ccid.BrandTrim());
获取SIMD指令集类的信息也很方便——
printf("CCPUID.MMX:\t%d\t// hw: %d\n", ccid.mmx(), ccid.hwmmx());
printf("CCPUID.SSE:\t%d\t// hw: %d\n", ccid.sse(), ccid.hwsse());
for(i=1; i
{
if(ccid.hwsse()>=i) printf("\t%s\n", CCPUID::SseNames[i]);
}
printf("SSE4A:\t%d\n", ccid.GetField(CPUF_SSE4A));
printf("AES:\t%d\n", ccid.GetField(CPUF_AES));
printf("PCLMULQDQ:\t%d\n", ccid.GetField(CPUF_PCLMULQDQ));
printf("CCPUID.AVX:\t%d\t// hw: %d\n", ccid.avx(), ccid.hwavx());
for(i=1; i
{
if(ccid.hwavx()>=i) printf("\t%s\n", CCPUID::AvxNames[i]);
}
printf("F16C:\t%d\n", ccid.GetField(CPUF_F16C));
printf("FMA:\t%d\n", ccid.GetField(CPUF_FMA));
printf("FMA4:\t%d\n", ccid.GetField(CPUF_FMA4));
printf("XOP:\t%d\n", ccid.GetField(CPUF_XOP));
printf("CCPUID.MMX:\t%d\t// hw: %d\n", ccid.mmx(), ccid.hwmmx());
printf("CCPUID.SSE:\t%d\t// hw: %d\n", ccid.sse(), ccid.hwsse());
for(i=1; i
{
if (ccid.hwsse()>=i)printf("\t%s\n", CCPUID::SseNames[i]);
}
printf("SSE4A:\t%d\n", ccid.GetField(CPUF_SSE4A));
printf("AES:\t%d\n", ccid.GetField(CPUF_AES));
printf("PCLMULQDQ:\t%d\n", ccid.GetField(CPUF_PCLMULQDQ));
printf("CCPUID.AVX:\t%d\t// hw: %d\n", ccid.avx(), ccid.hwavx());
for(i=1; i
{
if (ccid.hwavx()>=i)printf("\t%s\n", CCPUID::AvxNames[i]);
}
printf("F16C:\t%d\n", ccid.GetField(CPUF_F16C));
printf("FMA:\t%d\n", ccid.GetField(CPUF_FMA));
printf("FMA4:\t%d\n", ccid.GetField(CPUF_FMA4));
printf("XOP:\t%d\n", ccid.GetField(CPUF_XOP));
上面与前面博文中的代码差不多,只不过将全局函数变为CCPUID对象的成员函数而已,例如 simd_sse_names变为CCPUID::SseNames、getcpuidfield变为了ccid.GetField。
2.2 显示所有的CPUID信息
因为CCPUID类缓存了CPUID信息,而且还有CPUFDesc描述信息数组,所以编写显示所有的CPUID信息的程序十分容易。
我把它分为两个函数—— prtCcpuid:是外循环,对每一条CPUID信息调用prtCcpuid_Item函数。 prtCcpuid_Item:是内循环,在CCPUID::CPUFDesc数组中找到功能号相同的CPUIDFIELD子集,然后逐一输出该字段的数值、名称、描述等信息。
代码如下——
// 打印CPUID字段_某项.
voidprtCcpuid_Item(INT32fid,INT32fidsub,constINT32CPUInfo[4])
{
staticconstchar* RegName[4] = {"EAX","EBX","ECX","EDX"};
INT32mask = CPUIDFIELD_MASK_FID | CPUIDFIELD_MASK_FIDSUB;
INT32cur = CPUIDFIELD_MAKE(fid, fidsub, 0, 0, 1) & mask;
inti;
for(i=0; i<:cpufdesclen>
{
constCPUIDFIELDDESC& v = CCPUID::CPUFDesc[i];
if((v.cpuf&mask)==cur)
{
CPUIDFIELD f = v.cpuf;
intbits = CPUIDFIELD_LEN(f);
intpos = CPUIDFIELD_POS(f);
intreg = CPUIDFIELD_REG(f);
UINT32n = getcpuidfield_buf(CPUInfo, f);//UINT32 n = __GETBITS32(CPUInfo[reg], pos, bits);
if(bits>1)
{
printf("\t%s[%2d:%2d]", RegName[reg], pos+bits-1, pos);
}
else
{
printf("\t%s[ %2d]", RegName[reg], pos);
}
printf("=%s:\t0x%X\t(%u)", v.szName, n, n);
if(bShowDesc)
{
printf("\t// %s", v.szDesc);
}
printf("\n");
}
}
}
// 打印CPUID字段.
voidprtCcpuid(constCCPUID& ccid)
{
inti;
for(i=0; i
{
constCPUIDINFO& v = ccid.Info[i];
printf("0x%.8X[%d]:\t%.8X\t%.8X\t%.8X\t%.8X\n", v.fid, v.fidsub, v.dw[0], v.dw[1], v.dw[2], v.dw[3]);
// 检查子功能号. 如果是规范的子功能号,便故意设为0,根据子功能号0的字段来解析各个子功能号的信息。
INT32fidsub = v.fidsub;
switch(v.fid)
{
case0x4: fidsub=0;
case0xB: fidsub=0;
case0x8000001D: fidsub=0;
}
// item
prtCcpuid_Item(v.fid, fidsub, v.dw);
// otheritem
if(0==v.fid)// Vendor-ID (Function 02h)
{
printf("\tVendor:\t%s\n", ccid.Vendor());
}
elseif(0x80000004==v.fid)// Processor Brand String (Function 80000002h,80000003h,80000004h)
{
printf("\tBrand:\t%s\n", ccid.Brand());
}
elseif(0x2==v.fid)// Cache Descriptors (Function 02h)
{
for(intj=0; j<=3; ++j)
{
INT32n = v.dw[j];
if(n>0)// 最高位为0,且不是全0
{
for(intk=0; k<=3; ++k)
{
if(j>0 || k>0)// EAX的低8位不是缓存信息
{
intby = n & 0x00FF;
if(by>0)
{
printf("\t0x%.2X:\t%s\n", by, CCPUID::CacheDesc[by]);
}
}
n >>= 8;
}
}
}
}
}
}
// 打印CPUID字段_某项.
void prtCcpuid_Item(INT32 fid, INT32 fidsub, const INT32 CPUInfo[4])
{
static const char* RegName[4] = { "EAX", "EBX", "ECX", "EDX" };
INT32 mask = CPUIDFIELD_MASK_FID | CPUIDFIELD_MASK_FIDSUB;
INT32 cur = CPUIDFIELD_MAKE(fid, fidsub, 0, 0, 1) & mask;
int i;
for(i=0; i<:cpufdesclen>
{
const CPUIDFIELDDESC& v = CCPUID::CPUFDesc[i];
if ((v.cpuf&mask)==cur)
{
CPUIDFIELD f = v.cpuf;
int bits = CPUIDFIELD_LEN(f);
int pos = CPUIDFIELD_POS(f);
int reg = CPUIDFIELD_REG(f);
UINT32 n = getcpuidfield_buf(CPUInfo, f);//UINT32 n = __GETBITS32(CPUInfo[reg], pos, bits);
if (bits>1)
{
printf("\t%s[%2d:%2d]", RegName[reg], pos+bits-1, pos);
}
else
{
printf("\t%s[ %2d]", RegName[reg], pos);
}
printf("=%s:\t0x%X\t(%u)", v.szName, n, n);
if (bShowDesc)
{
printf("\t// %s", v.szDesc);
}
printf("\n");
}
}
}
// 打印CPUID字段.
void prtCcpuid(const CCPUID& ccid)
{
int i;
for(i=0; i
{
const CPUIDINFO& v = ccid.Info[i];
printf("0x%.8X[%d]:\t%.8X\t%.8X\t%.8X\t%.8X\n", v.fid, v.fidsub, v.dw[0], v.dw[1], v.dw[2], v.dw[3]);
// 检查子功能号. 如果是规范的子功能号,便故意设为0,根据子功能号0的字段来解析各个子功能号的信息。
INT32 fidsub = v.fidsub;
switch(v.fid)
{
case 0x4: fidsub=0;
case 0xB: fidsub=0;
case 0x8000001D: fidsub=0;
}
// item
prtCcpuid_Item(v.fid, fidsub, v.dw);
// otheritem
if (0==v.fid)// Vendor-ID (Function 02h)
{
printf("\tVendor:\t%s\n", ccid.Vendor());
}
else if (0x80000004==v.fid)// Processor Brand String (Function 80000002h,80000003h,80000004h)
{
printf("\tBrand:\t%s\n", ccid.Brand());
}
else if (0x2==v.fid)// Cache Descriptors (Function 02h)
{
for(int j=0; j<=3; ++j)
{
INT32 n = v.dw[j];
if (n>0)// 最高位为0,且不是全0
{
for(int k=0; k<=3; ++k)
{
if (j>0 || k>0)// EAX的低8位不是缓存信息
{
int by = n & 0x00FF;
if (by>0)
{
printf("\t0x%.2X:\t%s\n", by, CCPUID::CacheDesc[by]);
}
}
n >>= 8;
}
}
}
}
}
}
prtCcpuid函数中有两个技巧—— 1. 处理规范子功能号。检查子功能号,如果是规范的子功能号,便故意设为0,根据子功能号0的字段来解析各个子功能号的信息。 2. 处理特殊功能号。对于功能0和功能80000004h,可以利用Vendor、Brand这两个成员函数。对于功能2(缓存信息),可以利用CCPUID::CacheDesc数组来解析。
三、全部代码
3.1 头文件的全部代码
ccpuid.h——
#if _MSC_VER > 1000
#pragma once
#endif
#ifndef __CCPUID_H_INCLUDED
#define __CCPUID_H_INCLUDED
#include // NULL等标准宏和类型.
#include // INT32、UINT32等规范类型名.
#if _MSC_VER >=1400 // VC2005才支持intrin.h
#include // 所有Intrinsics函数.
#else
#include // MMX, SSE, SSE2
#endif
#if defined __cplusplus
extern"C"{
#endif
// __cpuid,__cpuidex
#if defined(_WIN64)
// 64位下不支持内联汇编. 应使用__cpuid、__cpuidex等Intrinsics函数.
#else
#if _MSC_VER < 1600 // VS2010. 据说VC2008 SP1之后才支持__cpuidex
inlinevoid__cpuidex(INT32CPUInfo[4],INT32InfoType,INT32ECXValue)
{
if(0==CPUInfo)return;
_asm{
// load. 读取参数到寄存器.
mov edi, CPUInfo;// 准备用edi寻址CPUInfo
mov eax, InfoType;
mov ecx, ECXValue;
// CPUID
cpuid;
// save. 将寄存器保存到CPUInfo
mov [edi], eax;
mov [edi+4], ebx;
mov [edi+8], ecx;
mov [edi+12], edx;
}
}
#endif // #if _MSC_VER < 1600 // VS2010. 据说VC2008 SP1之后才支持__cpuidex
#if _MSC_VER < 1400 // VC2005才支持__cpuid
inlinevoid__cpuid(INT32CPUInfo[4],INT32InfoType)
{
__cpuidex(CPUInfo, InfoType, 0);
}
#endif // #if _MSC_VER < 1400 // VC2005才支持__cpuid
#endif // #if defined(_WIN64)
// CPUIDFIELD
typedefINT32CPUIDFIELD;
#define CPUIDFIELD_MASK_POS 0x0000001F // 位偏移. 0~31.
#define CPUIDFIELD_MASK_LEN 0x000003E0 // 位长. 1~32
#define CPUIDFIELD_MASK_REG 0x00000C00 // 寄存器. 0=EAX, 1=EBX, 2=ECX, 3=EDX.
#define CPUIDFIELD_MASK_FIDSUB 0x000FF000 // 子功能号(低8位).
#define CPUIDFIELD_MASK_FID 0xFFF00000 // 功能号(最高4位 和 低8位).
#define CPUIDFIELD_SHIFT_POS 0
#define CPUIDFIELD_SHIFT_LEN 5
#define CPUIDFIELD_SHIFT_REG 10
#define CPUIDFIELD_SHIFT_FIDSUB 12
#define CPUIDFIELD_SHIFT_FID 20
#define CPUIDFIELD_MAKE(fid,fidsub,reg,pos,len) (((fid)&0xF0000000) \
| ((fid)<
| ((fidsub)<
| ((reg)<
| ((pos)<
| (((len)-1)<
)
#define CPUIDFIELD_FID(cpuidfield) ( ((cpuidfield)&0xF0000000) | (((cpuidfield) & 0x0FF00000)>>CPUIDFIELD_SHIFT_FID) )
#define CPUIDFIELD_FIDSUB(cpuidfield) ( ((cpuidfield) & CPUIDFIELD_MASK_FIDSUB)>>CPUIDFIELD_SHIFT_FIDSUB )
#define CPUIDFIELD_REG(cpuidfield) ( ((cpuidfield) & CPUIDFIELD_MASK_REG)>>CPUIDFIELD_SHIFT_REG )
#define CPUIDFIELD_POS(cpuidfield) ( ((cpuidfield) & CPUIDFIELD_MASK_POS)>>CPUIDFIELD_SHIFT_POS )
#define CPUIDFIELD_LEN(cpuidfield) ( (((cpuidfield) & CPUIDFIELD_MASK_LEN)>>CPUIDFIELD_SHIFT_LEN) + 1 )
typedefstructtagCPUIDFIELDDESC{
CPUIDFIELD cpuf;
INT32reserved;
constchar* szName;
constchar* szDesc;
}CPUIDFIELDDESC;
#define CPUF_LFuncStd CPUIDFIELD_MAKE(0,0,0,0,32)
#define CPUF_Stepping CPUIDFIELD_MAKE(1,0,0,0,4)
#define CPUF_BaseModel CPUIDFIELD_MAKE(1,0,0,4,4)
#define CPUF_BaseFamily CPUIDFIELD_MAKE(1,0,0,8,4)
#define CPUF_ProcessorType CPUIDFIELD_MAKE(1,0,0,12,2)
#define CPUF_ExtModel CPUIDFIELD_MAKE(1,0,0,16,4)
#define CPUF_ExtFamily CPUIDFIELD_MAKE(1,0,0,20,8)
#define CPUF_BrandId8 CPUIDFIELD_MAKE(1,0,1,0,8)
#define CPUF_CLFlush CPUIDFIELD_MAKE(1,0,1,8,8)
#define CPUF_MaxApicId CPUIDFIELD_MAKE(1,0,1,16,8)
#define CPUF_ApicId CPUIDFIELD_MAKE(1,0,1,24,8)
#define CPUF_SSE3 CPUIDFIELD_MAKE(1,0,2,0,1)
#define CPUF_PCLMULQDQ CPUIDFIELD_MAKE(1,0,2,1,1)
#define CPUF_DTES64 CPUIDFIELD_MAKE(1,0,2,2,1)
#define CPUF_MONITOR CPUIDFIELD_MAKE(1,0,2,3,1)
#define CPUF_DS_CPL CPUIDFIELD_MAKE(1,0,2,4,1)
#define CPUF_VMX CPUIDFIELD_MAKE(1,0,2,5,1)
#define CPUF_SMX CPUIDFIELD_MAKE(1,0,2,6,1)
#define CPUF_EIST CPUIDFIELD_MAKE(1,0,2,7,1)
#define CPUF_TM2 CPUIDFIELD_MAKE(1,0,2,8,1)
#define CPUF_SSSE3 CPUIDFIELD_MAKE(1,0,2,9,1)
#define CPUF_CNXT_ID CPUIDFIELD_MAKE(1,0,2,10,1)
#define CPUF_FMA CPUIDFIELD_MAKE(1,0,2,12,1)
#define CPUF_CMPXCHG16B CPUIDFIELD_MAKE(1,0,2,13,1)
#define CPUF_xTPR CPUIDFIELD_MAKE(1,0,2,14,1)
#define CPUF_PDCM CPUIDFIELD_MAKE(1,0,2,15,1)
#define CPUF_PCID CPUIDFIELD_MAKE(1,0,2,17,1)
#define CPUF_DCA CPUIDFIELD_MAKE(1,0,2,18,1)
#define CPUF_SSE41 CPUIDFIELD_MAKE(1,0,2,19,1)
#define CPUF_SSE42 CPUIDFIELD_MAKE(1,0,2,20,1)
#define CPUF_x2APIC CPUIDFIELD_MAKE(1,0,2,21,1)
#define CPUF_MOVBE CPUIDFIELD_MAKE(1,0,2,22,1)
#define CPUF_POPCNT CPUIDFIELD_MAKE(1,0,2,23,1)
#define CPUF_TSC_DEADLINE CPUIDFIELD_MAKE(1,0,2,24,1)
#define CPUF_AES CPUIDFIELD_MAKE(1,0,2,25,1)
#define CPUF_XSAVE CPUIDFIELD_MAKE(1,0,2,26,1)
#define CPUF_OSXSAVE CPUIDFIELD_MAKE(1,0,2,27,1)
#define CPUF_AVX CPUIDFIELD_MAKE(1,0,2,28,1)
#define CPUF_F16C CPUIDFIELD_MAKE(1,0,2,29,1)
#define CPUF_RDRAND CPUIDFIELD_MAKE(1,0,2,30,1)
#define CPUF_FPU CPUIDFIELD_MAKE(1,0,3,0,1)
#define CPUF_VME CPUIDFIELD_MAKE(1,0,3,1,1)
#define CPUF_DE CPUIDFIELD_MAKE(1,0,3,2,1)
#define CPUF_PSE CPUIDFIELD_MAKE(1,0,3,3,1)
#define CPUF_TSC CPUIDFIELD_MAKE(1,0,3,4,1)
#define CPUF_MSR CPUIDFIELD_MAKE(1,0,3,5,1)
#define CPUF_PAE CPUIDFIELD_MAKE(1,0,3,6,1)
#define CPUF_MCE CPUIDFIELD_MAKE(1,0,3,7,1)
#define CPUF_CX8 CPUIDFIELD_MAKE(1,0,3,8,1)
#define CPUF_APIC CPUIDFIELD_MAKE(1,0,3,9,1)
#define CPUF_SEP CPUIDFIELD_MAKE(1,0,3,11,1)
#define CPUF_MTRR CPUIDFIELD_MAKE(1,0,3,12,1)
#define CPUF_PGE CPUIDFIELD_MAKE(1,0,3,13,1)
#define CPUF_MCA CPUIDFIELD_MAKE(1,0,3,14,1)
#define CPUF_CMOV CPUIDFIELD_MAKE(1,0,3,15,1)
#define CPUF_PAT CPUIDFIELD_MAKE(1,0,3,16,1)
#define CPUF_PSE36 CPUIDFIELD_MAKE(1,0,3,17,1)
#define CPUF_PSN CPUIDFIELD_MAKE(1,0,3,18,1)
#define CPUF_CLFSH CPUIDFIELD_MAKE(1,0,3,19,1)
#define CPUF_DS CPUIDFIELD_MAKE(1,0,3,21,1)
#define CPUF_ACPI CPUIDFIELD_MAKE(1,0,3,22,1)
#define CPUF_MMX CPUIDFIELD_MAKE(1,0,3,23,1)
#define CPUF_FXSR CPUIDFIELD_MAKE(1,0,3,24,1)
#define CPUF_SSE CPUIDFIELD_MAKE(1,0,3,25,1)
#define CPUF_SSE2 CPUIDFIELD_MAKE(1,0,3,26,1)
#define CPUF_SS CPUIDFIELD_MAKE(1,0,3,27,1)
#define CPUF_HTT CPUIDFIELD_MAKE(1,0,3,28,1)
#define CPUF_TM CPUIDFIELD_MAKE(1,0,3,29,1)
#define CPUF_PBE CPUIDFIELD_MAKE(1,0,3,31,1)
#define CPUF_Cache_Type CPUIDFIELD_MAKE(4,0,0,0,5)
#define CPUF_Cache_Level CPUIDFIELD_MAKE(4,0,0,5,3)
#define CPUF_CACHE_SI CPUIDFIELD_MAKE(4,0,0,8,1)
#define CPUF_CACHE_FA CPUIDFIELD_MAKE(4,0,0,9,1)
#define CPUF_MaxApicIdShare CPUIDFIELD_MAKE(4,0,0,14,12)
#define CPUF_MaxApicIdCore CPUIDFIELD_MAKE(4,0,0,26,6)
#define CPUF_Cache_LineSize CPUIDFIELD_MAKE(4,0,1,0,12)
#define CPUF_Cache_Partitions CPUIDFIELD_MAKE(4,0,1,12,10)
#define CPUF_Cache_Ways CPUIDFIELD_MAKE(4,0,1,22,10)
#define CPUF_Cache_Sets CPUIDFIELD_MAKE(4,0,2,0,32)
#define CPUF_CACHE_INVD CPUIDFIELD_MAKE(4,0,3,0,1)
#define CPUF_CACHE_INCLUSIVENESS CPUIDFIELD_MAKE(4,0,3,1,1)
#define CPUF_CACHE_COMPLEXINDEX CPUIDFIELD_MAKE(4,0,3,2,1)
#define CPUF_MonLineSizeMin CPUIDFIELD_MAKE(5,0,0,0,16)
#define CPUF_MonLineSizeMax CPUIDFIELD_MAKE(5,0,1,0,16)
#define CPUF_EMX CPUIDFIELD_MAKE(5,0,2,0,1)
#define CPUF_IBE CPUIDFIELD_MAKE(5,0,2,1,1)
#define CPUF_MWAIT_Number_C0 CPUIDFIELD_MAKE(5,0,3,0,4)
#define CPUF_MWAIT_Number_C1 CPUIDFIELD_MAKE(5,0,3,4,4)
#define CPUF_MWAIT_Number_C2 CPUIDFIELD_MAKE(5,0,3,8,4)
#define CPUF_MWAIT_Number_C3 CPUIDFIELD_MAKE(5,0,3,12,4)
#define CPUF_MWAIT_Number_C4 CPUIDFIELD_MAKE(5,0,3,16,4)
#define CPUF_DTS CPUIDFIELD_MAKE(6,0,0,0,1)
#define CPUF_TURBO_BOOST CPUIDFIELD_MAKE(6,0,0,1,1)
#define CPUF_ARAT CPUIDFIELD_MAKE(6,0,0,2,1)
#define CPUF_PLN CPUIDFIELD_MAKE(6,0,0,4,1)
#define CPUF_ECMD CPUIDFIELD_MAKE(6,0,0,5,1)
#define CPUF_PTM CPUIDFIELD_MAKE(6,0,0,6,1)
#define CPUF_DTS_ITs CPUIDFIELD_MAKE(6,0,1,0,4)
#define CPUF_PERF CPUIDFIELD_MAKE(6,0,2,0,1)
#define CPUF_ACNT2 CPUIDFIELD_MAKE(6,0,2,1,1)
#define CPUF_ENERGY_PERF_BIAS CPUIDFIELD_MAKE(6,0,2,3,1)
#define CPUF_Max07Subleaf CPUIDFIELD_MAKE(7,0,0,0,32)
#define CPUF_FSGSBASE CPUIDFIELD_MAKE(7,0,1,0,1)
#define CPUF_BMI1 CPUIDFIELD_MAKE(7,0,1,3,1)
#define CPUF_HLE CPUIDFIELD_MAKE(7,0,1,4,1)
#define CPUF_AVX2 CPUIDFIELD_MAKE(7,0,1,5,1)
#define CPUF_SMEP CPUIDFIELD_MAKE(7,0,1,7,1)
#define CPUF_BMI2 CPUIDFIELD_MAKE(7,0,1,8,1)
#define CPUF_ERMS CPUIDFIELD_MAKE(7,0,1,9,1)
#define CPUF_INVPCID CPUIDFIELD_MAKE(7,0,1,10,1)
#define CPUF_RTM CPUIDFIELD_MAKE(7,0,1,11,1)
#define CPUF_PLATFORM_DCA_CAP CPUIDFIELD_MAKE(9,0,0,0,32)
#define CPUF_APM_Version CPUIDFIELD_MAKE(0xA,0,0,0,8)
#define CPUF_APM_Counters CPUIDFIELD_MAKE(0xA,0,0,8,8)
#define CPUF_APM_Bits CPUIDFIELD_MAKE(0xA,0,0,16,8)
#define CPUF_APM_Length CPUIDFIELD_MAKE(0xA,0,0,24,8)
#define CPUF_APM_CC CPUIDFIELD_MAKE(0xA,0,1,0,1)
#define CPUF_APM_IR CPUIDFIELD_MAKE(0xA,0,1,1,1)
#define CPUF_APM_RC CPUIDFIELD_MAKE(0xA,0,1,2,1)
#define CPUF_APM_LLCR CPUIDFIELD_MAKE(0xA,0,1,3,1)
#define CPUF_APM_LLCM CPUIDFIELD_MAKE(0xA,0,1,4,1)
#define CPUF_APM_BIR CPUIDFIELD_MAKE(0xA,0,1,5,1)
#define CPUF_APM_BMR CPUIDFIELD_MAKE(0xA,0,1,6,1)
#define CPUF_APM_FC_Number CPUIDFIELD_MAKE(0xA,0,3,0,5)
#define CPUF_APM_FC_Bits CPUIDFIELD_MAKE(0xA,0,3,5,8)
#define CPUF_Topology_Bits CPUIDFIELD_MAKE(0xB,0,0,0,5)
#define CPUF_Topology_Number CPUIDFIELD_MAKE(0xB,0,1,0,16)
#define CPUF_Topology_Level CPUIDFIELD_MAKE(0xB,0,2,0,8)
#define CPUF_Topology_Type CPUIDFIELD_MAKE(0xB,0,2,8,8)
#define CPUF_X2APICID CPUIDFIELD_MAKE(0xB,0,3,0,32)
#define CPUF_XFeatureSupportedMaskLo CPUIDFIELD_MAKE(0xD,0,0,0,32)
#define CPUF_XFeatureEnabledSizeMax CPUIDFIELD_MAKE(0xD,0,1,0,32)
#define CPUF_XFeatureSupportedSizeMax CPUIDFIELD_MAKE(0xD,0,2,0,32)
#define CPUF_XFeatureSupportedMaskHi CPUIDFIELD_MAKE(0xD,0,3,0,32)
#define CPUF_XSAVEOPT CPUIDFIELD_MAKE(0xD,1,0,0,1)
#define CPUF_YmmSaveStateSize CPUIDFIELD_MAKE(0xD,2,0,0,32)
#define CPUF_YmmSaveStateOffset CPUIDFIELD_MAKE(0xD,2,1,0,32)
#define CPUF_LwpSaveStateSize CPUIDFIELD_MAKE(0xD,62,0,0,32)
#define CPUF_LwpSaveStateOffset CPUIDFIELD_MAKE(0xD,62,1,0,32)
#define CPUF_LFuncExt CPUIDFIELD_MAKE(0x80000000,0,0,0,32)
#define CPUF_BrandId16 CPUIDFIELD_MAKE(0x80000001,0,1,0,16)
#define CPUF_PkgType CPUIDFIELD_MAKE(0x80000001,0,1,28,4)
#define CPUF_LahfSahf CPUIDFIELD_MAKE(0x80000001,0,2,0,1)
#define CPUF_CmpLegacy CPUIDFIELD_MAKE(0x80000001,0,2,1,1)
#define CPUF_SVM CPUIDFIELD_MAKE(0x80000001,0,2,2,1)
#define CPUF_ExtApicSpace CPUIDFIELD_MAKE(0x80000001,0,2,3,1)
#define CPUF_AltMovCr8 CPUIDFIELD_MAKE(0x80000001,0,2,4,1)
#define CPUF_ABM CPUIDFIELD_MAKE(0x80000001,0,2,5,1)
#define CPUF_SSE4A CPUIDFIELD_MAKE(0x80000001,0,2,6,1)
#define CPUF_MisAlignSse CPUIDFIELD_MAKE(0x80000001,0,2,7,1)
#define CPUF_3DNowPrefetch CPUIDFIELD_MAKE(0x80000001,0,2,8,1)
#define CPUF_OSVW CPUIDFIELD_MAKE(0x80000001,0,2,9,1)
#define CPUF_IBS CPUIDFIELD_MAKE(0x80000001,0,2,10,1)
#define CPUF_XOP CPUIDFIELD_MAKE(0x80000001,0,2,11,1)
#define CPUF_SKINIT CPUIDFIELD_MAKE(0x80000001,0,2,12,1)
#define CPUF_WDT CPUIDFIELD_MAKE(0x80000001,0,2,13,1)
#define CPUF_LWP CPUIDFIELD_MAKE(0x80000001,0,2,15,1)
#define CPUF_FMA4 CPUIDFIELD_MAKE(0x80000001,0,2,16,1)
#define CPUF_BIT_NODEID CPUIDFIELD_MAKE(0x80000001,0,2,19,1)
#define CPUF_TBM CPUIDFIELD_MAKE(0x80000001,0,2,21,1)
#define CPUF_TopologyExtensions CPUIDFIELD_MAKE(0x80000001,0,2,22,1)
#define CPUF_SYSCALL CPUIDFIELD_MAKE(0x80000001,0,3,11,1)
#define CPUF_XD CPUIDFIELD_MAKE(0x80000001,0,3,20,1)
#define CPUF_MmxExt CPUIDFIELD_MAKE(0x80000001,0,3,22,1)
#define CPUF_FFXSR CPUIDFIELD_MAKE(0x80000001,0,3,25,1)
#define CPUF_Page1GB CPUIDFIELD_MAKE(0x80000001,0,3,26,1)
#define CPUF_RDTSCP CPUIDFIELD_MAKE(0x80000001,0,3,27,1)
#define CPUF_LM CPUIDFIELD_MAKE(0x80000001,0,3,29,1)
#define CPUF_3DNowExt CPUIDFIELD_MAKE(0x80000001,0,3,30,1)
#define CPUF_3DNow CPUIDFIELD_MAKE(0x80000001,0,3,31,1)
#define CPUF_L1ITlb2and4MSize CPUIDFIELD_MAKE(0x80000005,0,0,0,8)
#define CPUF_L1ITlb2and4MAssoc CPUIDFIELD_MAKE(0x80000005,0,0,8,8)
#define CPUF_L1DTlb2and4MSize CPUIDFIELD_MAKE(0x80000005,0,0,16,8)
#define CPUF_L1DTlb2and4MAssoc CPUIDFIELD_MAKE(0x80000005,0,0,24,8)
#define CPUF_L1ITlb4KSize CPUIDFIELD_MAKE(0x80000005,0,1,0,8)
#define CPUF_L1ITlb4KAssoc CPUIDFIELD_MAKE(0x80000005,0,1,8,8)
#define CPUF_L1DTlb4KSize CPUIDFIELD_MAKE(0x80000005,0,1,16,8)
#define CPUF_L1DTlb4KAssoc CPUIDFIELD_MAKE(0x80000005,0,1,24,8)
#define CPUF_L1DcLineSize CPUIDFIELD_MAKE(0x80000005,0,2,0,8)
#define CPUF_L1DcLinesPerTag CPUIDFIELD_MAKE(0x80000005,0,2,8,8)
#define CPUF_L1DcAssoc CPUIDFIELD_MAKE(0x80000005,0,2,16,8)
#define CPUF_L1DcSize CPUIDFIELD_MAKE(0x80000005,0,2,24,8)
#define CPUF_L1IcLineSize CPUIDFIELD_MAKE(0x80000005,0,3,0,8)
#define CPUF_L1IcLinesPerTag CPUIDFIELD_MAKE(0x80000005,0,3,8,8)
#define CPUF_L1IcAssoc CPUIDFIELD_MAKE(0x80000005,0,3,16,8)
#define CPUF_L1IcSize CPUIDFIELD_MAKE(0x80000005,0,3,24,8)
#define CPUF_L2ITlb2and4MSize CPUIDFIELD_MAKE(0x80000006,0,0,0,12)
#define CPUF_L2ITlb2and4MAssoc CPUIDFIELD_MAKE(0x80000006,0,0,12,4)
#define CPUF_L2DTlb2and4MSize CPUIDFIELD_MAKE(0x80000006,0,0,16,12)
#define CPUF_L2DTlb2and4MAssoc CPUIDFIELD_MAKE(0x80000006,0,0,28,4)
#define CPUF_L2ITlb4KSize CPUIDFIELD_MAKE(0x80000006,0,1,0,12)
#define CPUF_L2ITlb4KAssoc CPUIDFIELD_MAKE(0x80000006,0,1,12,4)
#define CPUF_L2DTlb4KSize CPUIDFIELD_MAKE(0x80000006,0,1,16,12)
#define CPUF_L2DTlb4KAssoc CPUIDFIELD_MAKE(0x80000006,0,1,28,4)
#define CPUF_L2LineSize CPUIDFIELD_MAKE(0x80000006,0,2,0,8)
#define CPUF_L2LinesPerTag CPUIDFIELD_MAKE(0x80000006,0,2,8,4)
#define CPUF_L2Assoc CPUIDFIELD_MAKE(0x80000006,0,2,12,4)
#define CPUF_L2Size CPUIDFIELD_MAKE(0x80000006,0,2,16,16)
#define CPUF_L3LineSize CPUIDFIELD_MAKE(0x80000006,0,3,0,8)
#define CPUF_L3LinesPerTag CPUIDFIELD_MAKE(0x80000006,0,3,8,4)
#define CPUF_L3Assoc CPUIDFIELD_MAKE(0x80000006,0,3,12,4)
#define CPUF_L3Size CPUIDFIELD_MAKE(0x80000006,0,3,18,14)
#define CPUF_TS CPUIDFIELD_MAKE(0x80000007,0,3,0,1)
#define CPUF_FID CPUIDFIELD_MAKE(0x80000007,0,3,1,1)
#define CPUF_VID CPUIDFIELD_MAKE(0x80000007,0,3,2,1)
#define CPUF_TTP CPUIDFIELD_MAKE(0x80000007,0,3,3,1)
#define CPUF_HTC CPUIDFIELD_MAKE(0x80000007,0,3,4,1)
#define CPUF_100MHzSteps CPUIDFIELD_MAKE(0x80000007,0,3,6,1)
#define CPUF_HwPstate CPUIDFIELD_MAKE(0x80000007,0,3,7,1)
#define CPUF_TscInvariant CPUIDFIELD_MAKE(0x80000007,0,3,8,1)
#define CPUF_CPB CPUIDFIELD_MAKE(0x80000007,0,3,9,1)
#define CPUF_EffFreqRO CPUIDFIELD_MAKE(0x80000007,0,3,10,1)
#define CPUF_PhysAddrSize CPUIDFIELD_MAKE(0x80000008,0,0,0,8)
#define CPUF_LinAddrSize CPUIDFIELD_MAKE(0x80000008,0,0,8,8)
#define CPUF_GuestPhysAddrSize CPUIDFIELD_MAKE(0x80000008,0,0,16,8)
#define CPUF_NC CPUIDFIELD_MAKE(0x80000008,0,2,0,8)
#define CPUF_ApicIdCoreIdSize CPUIDFIELD_MAKE(0x80000008,0,2,12,4)
#define CPUF_SvmRev CPUIDFIELD_MAKE(0x8000000A,0,0,0,8)
#define CPUF_NASID CPUIDFIELD_MAKE(0x8000000A,0,1,0,32)
#define CPUF_NP CPUIDFIELD_MAKE(0x8000000A,0,3,0,1)
#define CPUF_LbrVirt CPUIDFIELD_MAKE(0x8000000A,0,3,1,1)
#define CPUF_SVML CPUIDFIELD_MAKE(0x8000000A,0,3,2,1)
#define CPUF_NRIPS CPUIDFIELD_MAKE(0x8000000A,0,3,3,1)
#define CPUF_TscRateMsr CPUIDFIELD_MAKE(0x8000000A,0,3,4,1)
#define CPUF_VmcbClean CPUIDFIELD_MAKE(0x8000000A,0,3,5,1)
#define CPUF_FlushByAsid CPUIDFIELD_MAKE(0x8000000A,0,3,6,1)
#define CPUF_DecodeAssists CPUIDFIELD_MAKE(0x8000000A,0,3,7,1)
#define CPUF_PauseFilter CPUIDFIELD_MAKE(0x8000000A,0,3,10,1)
#define CPUF_PauseFilterThreshold CPUIDFIELD_MAKE(0x8000000A,0,3,12,1)
#define CPUF_L1ITlb1GSize CPUIDFIELD_MAKE(0x80000019,0,0,0,12)
#define CPUF_L1ITlb1GAssoc CPUIDFIELD_MAKE(0x80000019,0,0,12,4)
#define CPUF_L1DTlb1GSize CPUIDFIELD_MAKE(0x80000019,0,0,16,12)
#define CPUF_L1DTlb1GAssoc CPUIDFIELD_MAKE(0x80000019,0,0,28,4)
#define CPUF_L2ITlb1GSize CPUIDFIELD_MAKE(0x80000019,0,1,0,12)
#define CPUF_L2ITlb1GAssoc CPUIDFIELD_MAKE(0x80000019,0,1,12,4)
#define CPUF_L2DTlb1GSize CPUIDFIELD_MAKE(0x80000019,0,1,16,12)
#define CPUF_L2DTlb1GAssoc CPUIDFIELD_MAKE(0x80000019,0,1,28,4)
#define CPUF_FP128 CPUIDFIELD_MAKE(0x8000001A,0,0,0,1)
#define CPUF_MOVU CPUIDFIELD_MAKE(0x8000001A,0,0,1,1)
#define CPUF_IBSFFV CPUIDFIELD_MAKE(0x8000001B,0,0,0,1)
#define CPUF_FetchSam CPUIDFIELD_MAKE(0x8000001B,0,0,1,1)
#define CPUF_OpSam CPUIDFIELD_MAKE(0x8000001B,0,0,2,1)
#define CPUF_RdWrOpCnt CPUIDFIELD_MAKE(0x8000001B,0,0,3,1)
#define CPUF_OpCnt CPUIDFIELD_MAKE(0x8000001B,0,0,4,1)
#define CPUF_BrnTrgt CPUIDFIELD_MAKE(0x8000001B,0,0,5,1)
#define CPUF_OpCntExt CPUIDFIELD_MAKE(0x8000001B,0,0,6,1)
#define CPUF_RipInvalidChk CPUIDFIELD_MAKE(0x8000001B,0,0,7,1)
#define CPUF_LwpAvail CPUIDFIELD_MAKE(0x8000001C,0,0,0,1)
#define CPUF_LwpVAL CPUIDFIELD_MAKE(0x8000001C,0,0,1,1)
#define CPUF_LwpIRE CPUIDFIELD_MAKE(0x8000001C,0,0,2,1)
#define CPUF_LwpBRE CPUIDFIELD_MAKE(0x8000001C,0,0,3,1)
#define CPUF_LwpDME CPUIDFIELD_MAKE(0x8000001C,0,0,4,1)
#define CPUF_LwpCNH CPUIDFIELD_MAKE(0x8000001C,0,0,5,1)
#define CPUF_LwpRNH CPUIDFIELD_MAKE(0x8000001C,0,0,6,1)
#define CPUF_LwpInt CPUIDFIELD_MAKE(0x8000001C,0,0,31,1)
#define CPUF_LwpCbSize CPUIDFIELD_MAKE(0x8000001C,0,1,0,8)
#define CPUF_LwpEventSize CPUIDFIELD_MAKE(0x8000001C,0,1,8,8)
#define CPUF_LwpMaxEvents CPUIDFIELD_MAKE(0x8000001C,0,1,16,8)
#define CPUF_LwpEventOffset CPUIDFIELD_MAKE(0x8000001C,0,1,24,8)
#define CPUF_LwpLatencyMax CPUIDFIELD_MAKE(0x8000001C,0,2,0,5)
#define CPUF_LwpDataAddress CPUIDFIELD_MAKE(0x8000001C,0,2,5,1)
#define CPUF_LwpLatencyRnd CPUIDFIELD_MAKE(0x8000001C,0,2,6,3)
#define CPUF_LwpVersion CPUIDFIELD_MAKE(0x8000001C,0,2,9,7)
#define CPUF_LwpMinBufferSize CPUIDFIELD_MAKE(0x8000001C,0,2,16,8)
#define CPUF_LwpBranchPrediction CPUIDFIELD_MAKE(0x8000001C,0,2,28,1)
#define CPUF_LwpIpFiltering CPUIDFIELD_MAKE(0x8000001C,0,2,29,1)
#define CPUF_LwpCacheLevels CPUIDFIELD_MAKE(0x8000001C,0,2,30,1)
#define CPUF_LwpCacheLatency CPUIDFIELD_MAKE(0x8000001C,0,2,31,1)
#define CPUF_D_LwpAvail CPUIDFIELD_MAKE(0x8000001C,0,3,0,1)
#define CPUF_D_LwpVAL CPUIDFIELD_MAKE(0x8000001C,0,3,1,1)
#define CPUF_D_LwpIRE CPUIDFIELD_MAKE(0x8000001C,0,3,2,1)
#define CPUF_D_LwpBRE CPUIDFIELD_MAKE(0x8000001C,0,3,3,1)
#define CPUF_D_LwpDME CPUIDFIELD_MAKE(0x8000001C,0,3,4,1)
#define CPUF_D_LwpCNH CPUIDFIELD_MAKE(0x8000001C,0,3,5,1)
#define CPUF_D_LwpRNH CPUIDFIELD_MAKE(0x8000001C,0,3,6,1)
#define CPUF_D_LwpInt CPUIDFIELD_MAKE(0x8000001C,0,3,31,1)
#define CPUF_CacheType CPUIDFIELD_MAKE(0x8000001D,0,0,0,5)
#define CPUF_CacheLevel CPUIDFIELD_MAKE(0x8000001D,0,0,5,3)
#define CPUF_SelfInitialization CPUIDFIELD_MAKE(0x8000001D,0,0,8,1)
#define CPUF_FullyAssociative CPUIDFIELD_MAKE(0x8000001D,0,0,9,1)
#define CPUF_NumSharingCache CPUIDFIELD_MAKE(0x8000001D,0,0,14,12)
#define CPUF_CacheLineSize CPUIDFIELD_MAKE(0x8000001D,0,1,0,12)
#define CPUF_CachePhysPartitions CPUIDFIELD_MAKE(0x8000001D,0,1,12,10)
#define CPUF_CacheNumWays CPUIDFIELD_MAKE(0x8000001D,0,1,22,10)
#define CPUF_CacheNumSets CPUIDFIELD_MAKE(0x8000001D,0,2,0,32)
#define CPUF_WBINVD CPUIDFIELD_MAKE(0x8000001D,0,3,0,1)
#define CPUF_CacheInclusive CPUIDFIELD_MAKE(0x8000001D,0,3,1,1)
#define CPUF_ExtendedApicId CPUIDFIELD_MAKE(0x8000001E,0,0,0,32)
#define CPUF_ComputeUnitId CPUIDFIELD_MAKE(0x8000001E,0,1,0,8)
#define CPUF_CoresPerComputeUnit CPUIDFIELD_MAKE(0x8000001E,0,1,8,2)
#define CPUF_NodeId CPUIDFIELD_MAKE(0x8000001E,0,2,0,8)
#define CPUF_NodesPerProcessor CPUIDFIELD_MAKE(0x8000001E,0,2,8,3)
// 取得位域
#ifndef __GETBITS32
#define __GETBITS32(src,pos,len) ( ((src)>>(pos)) & (((UINT32)-1)>>(32-len)) )
#endif
// 根据CPUIDFIELD从缓冲区中获取字段.
inlineUINT32getcpuidfield_buf(constINT32dwBuf[4], CPUIDFIELD cpuf)
{
return__GETBITS32(dwBuf[CPUIDFIELD_REG(cpuf)], CPUIDFIELD_POS(cpuf), CPUIDFIELD_LEN(cpuf));
}
// 根据CPUIDFIELD获取CPUID字段.
inlineUINT32getcpuidfield(CPUIDFIELD cpuf)
{
INT32dwBuf[4];
__cpuidex(dwBuf, CPUIDFIELD_FID(cpuf), CPUIDFIELD_FIDSUB(cpuf));
returngetcpuidfield_buf(dwBuf, cpuf);
}
// SSE系列指令集的支持级别. simd_sse_level 函数的返回值.
#define SIMD_SSE_NONE 0 // 不支持.
#define SIMD_SSE_1 1 // SSE
#define SIMD_SSE_2 2 // SSE2
#define SIMD_SSE_3 3 // SSE3
#define SIMD_SSE_3S 4 // SSSE3
#define SIMD_SSE_41 5 // SSE4.1
#define SIMD_SSE_42 6 // SSE4.2
// AVX系列指令集的支持级别. simd_avx_level 函数的返回值。
#define SIMD_AVX_NONE 0 // 不支持
#define SIMD_AVX_1 1 // AVX
#define SIMD_AVX_2 2 // AVX2
// functions
intcpu_getvendor(char* pvendor);
intcpu_getbrand(char* pbrand);
intsimd_mmx(int* phwmmx);
intsimd_sse_level(int* phwsse);
intsimd_avx_level(int* phwavx);
typedefstructtagCPUIDINFO{
INT32fid;
INT32fidsub;
union{
INT32dw[4];
struct{
INT32_eax;
INT32_ebx;
INT32_ecx;
INT32_edx;
};
};
}CPUIDINFO;
typedefCPUIDINFO* LPCPUIDINFO;
typedefconstCPUIDINFO* LPCCPUIDINFO;
#define MAX_CPUIDINFO 0x100 // CCPUID类中最多保存多少条CPUIDINFO信息。
#if defined __cplusplus
};
#endif
classCCPUID{
public:
enum{
CPUFDescLen = 292// CPUIDFIELD描述信息数组的长度.
};
staticconstCPUIDFIELDDESC CPUFDesc[CPUFDescLen];// CPUIDFIELD描述信息数组.
staticconstchar* CacheDesc[0x100];// 缓存描述信息数组.
staticconstchar* SseNames[7];// SSE级别的名称.
staticconstchar* AvxNames[3];// AVX级别的名称.
CPUIDINFO Info[MAX_CPUIDINFO+1];// CPUID信息数组.
CCPUID();
staticCCPUID& cur() {if(0==_cur._InfoCount){ _cur.RefreshAll(); }return_cur; }// 当前处理器的CCPUID.
intInfoCount()const{return_InfoCount; }// Info数组的有效项目数.
voidRefreshInfo();// 刷新信息.
voidRefreshProperty();// 刷新属性.
voidRefreshAll();// 刷新所有.
LPCCPUIDINFO GetInfo(INT32InfoType,INT32ECXValue=0)const;// 取得信息.
voidGetData(INT32CPUInfo[4],INT32InfoType,INT32ECXValue=0)const;// 取得数据.
UINT32GetField(CPUIDFIELD cpuf)const;// 取得CPUID字段
// Property
intLFuncStd()const{return_LFuncStd; }// 最大的主功能号.
intLFuncExt()const{return_LFuncExt; }// 最大的扩展功能号.
constchar* Vendor()const{return_Vendor; }// 厂商.
constchar* Brand()const{return_Brand; }// 商标.
constchar* BrandTrim()const{return_BrandTrim; }// 去掉首都空格后的商标.
intmmx()const{return_mmx; }// 系统支持MMX.
inthwmmx()const{return_hwmmx; }// 硬件支持MMX.
intsse()const{return_sse; }// 系统支持SSE.
inthwsse()const{return_hwsse; }// 硬件支持SSE.
intavx()const{return_avx; }// 系统支持AVX.
inthwavx()const{return_hwavx; }// 硬件支持AVX.
private:
staticCCPUID _cur;// 当前处理器的CCPUID. 为了方便日常使用.
int_InfoCount;// Info数组的有效项目数.
// Property
int_LFuncStd;// 最大的主功能号.
int_LFuncExt;// 最大的扩展功能号.
char_Vendor[13];// 厂商.
char_Brand[49];// 商标.
constchar* _BrandTrim;// 去掉首都空格后的商标.
int_mmx;// 系统支持MMX.
int_hwmmx;// 硬件支持MMX.
int_sse;// 系统支持SSE.
int_hwsse;// 硬件支持SSE.
int_avx;// 系统支持AVX.
int_hwavx;// 硬件支持AVX.
voidRefreshInfo_Put(INT32fid,INT32fidsub,INT32CPUInfo[4]);
intsimd_mmx(int* phwmmx)const;
intsimd_sse_level(int* phwsse)const;
intsimd_avx_level(int* phwavx)const;
};
#endif // #ifndef __CCPUID_H_INCLUDED
#if _MSC_VER > 1000
#pragma once
#endif
#ifndef __CCPUID_H_INCLUDED
#define __CCPUID_H_INCLUDED
#include // NULL等标准宏和类型.
#include // INT32、UINT32等规范类型名.
#if _MSC_VER >=1400// VC2005才支持intrin.h
#include // 所有Intrinsics函数.
#else
#include // MMX, SSE, SSE2
#endif
#if defined __cplusplus
extern "C" {
#endif
// __cpuid,__cpuidex
#if defined(_WIN64)
// 64位下不支持内联汇编. 应使用__cpuid、__cpuidex等Intrinsics函数.
#else
#if _MSC_VER < 1600// VS2010. 据说VC2008 SP1之后才支持__cpuidex
inline void __cpuidex(INT32 CPUInfo[4], INT32 InfoType, INT32 ECXValue)
{
if (0==CPUInfo)return;
_asm{
// load. 读取参数到寄存器.
mov edi, CPUInfo;// 准备用edi寻址CPUInfo
mov eax, InfoType;
mov ecx, ECXValue;
// CPUID
cpuid;
// save. 将寄存器保存到CPUInfo
mov[edi], eax;
mov[edi+4], ebx;
mov[edi+8], ecx;
mov[edi+12], edx;
}
}
#endif// #if _MSC_VER < 1600// VS2010. 据说VC2008 SP1之后才支持__cpuidex
#if _MSC_VER < 1400// VC2005才支持__cpuid
inline void __cpuid(INT32 CPUInfo[4], INT32 InfoType)
{
__cpuidex(CPUInfo, InfoType, 0);
}
#endif// #if _MSC_VER < 1400// VC2005才支持__cpuid
#endif// #if defined(_WIN64)
// CPUIDFIELD
typedef INT32 CPUIDFIELD;
#define CPUIDFIELD_MASK_POS0x0000001F// 位偏移. 0~31.
#define CPUIDFIELD_MASK_LEN0x000003E0// 位长. 1~32
#define CPUIDFIELD_MASK_REG0x00000C00// 寄存器. 0=EAX, 1=EBX, 2=ECX, 3=EDX.
#define CPUIDFIELD_MASK_FIDSUB0x000FF000// 子功能号(低8位).
#define CPUIDFIELD_MASK_FID0xFFF00000// 功能号(最高4位 和 低8位).
#define CPUIDFIELD_SHIFT_POS0
#define CPUIDFIELD_SHIFT_LEN5
#define CPUIDFIELD_SHIFT_REG10
#define CPUIDFIELD_SHIFT_FIDSUB12
#define CPUIDFIELD_SHIFT_FID20
#define CPUIDFIELD_MAKE(fid,fidsub,reg,pos,len)(((fid)&0xF0000000) \
| ((fid)<
| ((fidsub)<
| ((reg)<
| ((pos)<
| (((len)-1)<
)
#define CPUIDFIELD_FID(cpuidfield)( ((cpuidfield)&0xF0000000) | (((cpuidfield) & 0x0FF00000)>>CPUIDFIELD_SHIFT_FID) )
#define CPUIDFIELD_FIDSUB(cpuidfield)( ((cpuidfield) & CPUIDFIELD_MASK_FIDSUB)>>CPUIDFIELD_SHIFT_FIDSUB )
#define CPUIDFIELD_REG(cpuidfield)( ((cpuidfield) & CPUIDFIELD_MASK_REG)>>CPUIDFIELD_SHIFT_REG )
#define CPUIDFIELD_POS(cpuidfield)( ((cpuidfield) & CPUIDFIELD_MASK_POS)>>CPUIDFIELD_SHIFT_POS )
#define CPUIDFIELD_LEN(cpuidfield)( (((cpuidfield) & CPUIDFIELD_MASK_LEN)>>CPUIDFIELD_SHIFT_LEN) + 1 )
typedef struct tagCPUIDFIELDDESC{
CPUIDFIELDcpuf;
INT32reserved;
const char* szName;
const char* szDesc;
}CPUIDFIELDDESC;
#define CPUF_LFuncStdCPUIDFIELD_MAKE(0,0,0,0,32)
#define CPUF_SteppingCPUIDFIELD_MAKE(1,0,0,0,4)
#define CPUF_BaseModelCPUIDFIELD_MAKE(1,0,0,4,4)
#define CPUF_BaseFamilyCPUIDFIELD_MAKE(1,0,0,8,4)
#define CPUF_ProcessorTypeCPUIDFIELD_MAKE(1,0,0,12,2)
#define CPUF_ExtModelCPUIDFIELD_MAKE(1,0,0,16,4)
#define CPUF_ExtFamilyCPUIDFIELD_MAKE(1,0,0,20,8)
#define CPUF_BrandId8CPUIDFIELD_MAKE(1,0,1,0,8)
#define CPUF_CLFlushCPUIDFIELD_MAKE(1,0,1,8,8)
#define CPUF_MaxApicIdCPUIDFIELD_MAKE(1,0,1,16,8)
#define CPUF_ApicIdCPUIDFIELD_MAKE(1,0,1,24,8)
#define CPUF_SSE3CPUIDFIELD_MAKE(1,0,2,0,1)
#define CPUF_PCLMULQDQCPUIDFIELD_MAKE(1,0,2,1,1)
#define CPUF_DTES64CPUIDFIELD_MAKE(1,0,2,2,1)
#define CPUF_MONITORCPUIDFIELD_MAKE(1,0,2,3,1)
#define CPUF_DS_CPLCPUIDFIELD_MAKE(1,0,2,4,1)
#define CPUF_VMXCPUIDFIELD_MAKE(1,0,2,5,1)
#define CPUF_SMXCPUIDFIELD_MAKE(1,0,2,6,1)
#define CPUF_EISTCPUIDFIELD_MAKE(1,0,2,7,1)
#define CPUF_TM2CPUIDFIELD_MAKE(1,0,2,8,1)
#define CPUF_SSSE3CPUIDFIELD_MAKE(1,0,2,9,1)
#define CPUF_CNXT_IDCPUIDFIELD_MAKE(1,0,2,10,1)
#define CPUF_FMACPUIDFIELD_MAKE(1,0,2,12,1)
#define CPUF_CMPXCHG16BCPUIDFIELD_MAKE(1,0,2,13,1)
#define CPUF_xTPRCPUIDFIELD_MAKE(1,0,2,14,1)
#define CPUF_PDCMCPUIDFIELD_MAKE(1,0,2,15,1)
#define CPUF_PCIDCPUIDFIELD_MAKE(1,0,2,17,1)
#define CPUF_DCACPUIDFIELD_MAKE(1,0,2,18,1)
#define CPUF_SSE41CPUIDFIELD_MAKE(1,0,2,19,1)
#define CPUF_SSE42CPUIDFIELD_MAKE(1,0,2,20,1)
#define CPUF_x2APICCPUIDFIELD_MAKE(1,0,2,21,1)
#define CPUF_MOVBECPUIDFIELD_MAKE(1,0,2,22,1)
#define CPUF_POPCNTCPUIDFIELD_MAKE(1,0,2,23,1)
#define CPUF_TSC_DEADLINECPUIDFIELD_MAKE(1,0,2,24,1)
#define CPUF_AESCPUIDFIELD_MAKE(1,0,2,25,1)
#define CPUF_XSAVECPUIDFIELD_MAKE(1,0,2,26,1)
#define CPUF_OSXSAVECPUIDFIELD_MAKE(1,0,2,27,1)
#define CPUF_AVXCPUIDFIELD_MAKE(1,0,2,28,1)
#define CPUF_F16CCPUIDFIELD_MAKE(1,0,2,29,1)
#define CPUF_RDRANDCPUIDFIELD_MAKE(1,0,2,30,1)
#define CPUF_FPUCPUIDFIELD_MAKE(1,0,3,0,1)
#define CPUF_VMECPUIDFIELD_MAKE(1,0,3,1,1)
#define CPUF_DECPUIDFIELD_MAKE(1,0,3,2,1)
#define CPUF_PSECPUIDFIELD_MAKE(1,0,3,3,1)
#define CPUF_TSCCPUIDFIELD_MAKE(1,0,3,4,1)
#define CPUF_MSRCPUIDFIELD_MAKE(1,0,3,5,1)
#define CPUF_PAECPUIDFIELD_MAKE(1,0,3,6,1)
#define CPUF_MCECPUIDFIELD_MAKE(1,0,3,7,1)
#define CPUF_CX8CPUIDFIELD_MAKE(1,0,3,8,1)
#define CPUF_APICCPUIDFIELD_MAKE(1,0,3,9,1)
#define CPUF_SEPCPUIDFIELD_MAKE(1,0,3,11,1)
#define CPUF_MTRRCPUIDFIELD_MAKE(1,0,3,12,1)
#define CPUF_PGECPUIDFIELD_MAKE(1,0,3,13,1)
#define CPUF_MCACPUIDFIELD_MAKE(1,0,3,14,1)
#define CPUF_CMOVCPUIDFIELD_MAKE(1,0,3,15,1)
#define CPUF_PATCPUIDFIELD_MAKE(1,0,3,16,1)
#define CPUF_PSE36CPUIDFIELD_MAKE(1,0,3,17,1)
#define CPUF_PSNCPUIDFIELD_MAKE(1,0,3,18,1)
#define CPUF_CLFSHCPUIDFIELD_MAKE(1,0,3,19,1)
#define CPUF_DSCPUIDFIELD_MAKE(1,0,3,21,1)
#define CPUF_ACPICPUIDFIELD_MAKE(1,0,3,22,1)
#define CPUF_MMXCPUIDFIELD_MAKE(1,0,3,23,1)
#define CPUF_FXSRCPUIDFIELD_MAKE(1,0,3,24,1)
#define CPUF_SSECPUIDFIELD_MAKE(1,0,3,25,1)
#define CPUF_SSE2CPUIDFIELD_MAKE(1,0,3,26,1)
#define CPUF_SSCPUIDFIELD_MAKE(1,0,3,27,1)
#define CPUF_HTTCPUIDFIELD_MAKE(1,0,3,28,1)
#define CPUF_TMCPUIDFIELD_MAKE(1,0,3,29,1)
#define CPUF_PBECPUIDFIELD_MAKE(1,0,3,31,1)
#define CPUF_Cache_TypeCPUIDFIELD_MAKE(4,0,0,0,5)
#define CPUF_Cache_LevelCPUIDFIELD_MAKE(4,0,0,5,3)
#define CPUF_CACHE_SICPUIDFIELD_MAKE(4,0,0,8,1)
#define CPUF_CACHE_FACPUIDFIELD_MAKE(4,0,0,9,1)
#define CPUF_MaxApicIdShareCPUIDFIELD_MAKE(4,0,0,14,12)
#define CPUF_MaxApicIdCoreCPUIDFIELD_MAKE(4,0,0,26,6)
#define CPUF_Cache_LineSizeCPUIDFIELD_MAKE(4,0,1,0,12)
#define CPUF_Cache_PartitionsCPUIDFIELD_MAKE(4,0,1,12,10)
#define CPUF_Cache_WaysCPUIDFIELD_MAKE(4,0,1,22,10)
#define CPUF_Cache_SetsCPUIDFIELD_MAKE(4,0,2,0,32)
#define CPUF_CACHE_INVDCPUIDFIELD_MAKE(4,0,3,0,1)
#define CPUF_CACHE_INCLUSIVENESSCPUIDFIELD_MAKE(4,0,3,1,1)
#define CPUF_CACHE_COMPLEXINDEXCPUIDFIELD_MAKE(4,0,3,2,1)
#define CPUF_MonLineSizeMinCPUIDFIELD_MAKE(5,0,0,0,16)
#define CPUF_MonLineSizeMaxCPUIDFIELD_MAKE(5,0,1,0,16)
#define CPUF_EMXCPUIDFIELD_MAKE(5,0,2,0,1)
#define CPUF_IBECPUIDFIELD_MAKE(5,0,2,1,1)
#define CPUF_MWAIT_Number_C0CPUIDFIELD_MAKE(5,0,3,0,4)
#define CPUF_MWAIT_Number_C1CPUIDFIELD_MAKE(5,0,3,4,4)
#define CPUF_MWAIT_Number_C2CPUIDFIELD_MAKE(5,0,3,8,4)
#define CPUF_MWAIT_Number_C3CPUIDFIELD_MAKE(5,0,3,12,4)
#define CPUF_MWAIT_Number_C4CPUIDFIELD_MAKE(5,0,3,16,4)
#define CPUF_DTSCPUIDFIELD_MAKE(6,0,0,0,1)
#define CPUF_TURBO_BOOSTCPUIDFIELD_MAKE(6,0,0,1,1)
#define CPUF_ARATCPUIDFIELD_MAKE(6,0,0,2,1)
#define CPUF_PLNCPUIDFIELD_MAKE(6,0,0,4,1)
#define CPUF_ECMDCPUIDFIELD_MAKE(6,0,0,5,1)
#define CPUF_PTMCPUIDFIELD_MAKE(6,0,0,6,1)
#define CPUF_DTS_ITsCPUIDFIELD_MAKE(6,0,1,0,4)
#define CPUF_PERFCPUIDFIELD_MAKE(6,0,2,0,1)
#define CPUF_ACNT2CPUIDFIELD_MAKE(6,0,2,1,1)
#define CPUF_ENERGY_PERF_BIASCPUIDFIELD_MAKE(6,0,2,3,1)
#define CPUF_Max07SubleafCPUIDFIELD_MAKE(7,0,0,0,32)
#define CPUF_FSGSBASECPUIDFIELD_MAKE(7,0,1,0,1)
#define CPUF_BMI1CPUIDFIELD_MAKE(7,0,1,3,1)
#define CPUF_HLECPUIDFIELD_MAKE(7,0,1,4,1)
#define CPUF_AVX2CPUIDFIELD_MAKE(7,0,1,5,1)
#define CPUF_SMEPCPUIDFIELD_MAKE(7,0,1,7,1)
#define CPUF_BMI2CPUIDFIELD_MAKE(7,0,1,8,1)
#define CPUF_ERMSCPUIDFIELD_MAKE(7,0,1,9,1)
#define CPUF_INVPCIDCPUIDFIELD_MAKE(7,0,1,10,1)
#define CPUF_RTMCPUIDFIELD_MAKE(7,0,1,11,1)
#define CPUF_PLATFORM_DCA_CAPCPUIDFIELD_MAKE(9,0,0,0,32)
#define CPUF_APM_VersionCPUIDFIELD_MAKE(0xA,0,0,0,8)
#define CPUF_APM_CountersCPUIDFIELD_MAKE(0xA,0,0,8,8)
#define CPUF_APM_BitsCPUIDFIELD_MAKE(0xA,0,0,16,8)
#define CPUF_APM_LengthCPUIDFIELD_MAKE(0xA,0,0,24,8)
#define CPUF_APM_CCCPUIDFIELD_MAKE(0xA,0,1,0,1)
#define CPUF_APM_IRCPUIDFIELD_MAKE(0xA,0,1,1,1)
#define CPUF_APM_RCCPUIDFIELD_MAKE(0xA,0,1,2,1)
#define CPUF_APM_LLCRCPUIDFIELD_MAKE(0xA,0,1,3,1)