新版本——
http://www.cnblogs.com/zyl910/archive/2012/10/13/ccpuid_v103.html
作者:zyl910。
之前的ccpuid V1.01版只支持Windows和Linux平台。现在的V1.02版增加对Mac OS X平台的支持,还做了这些改进——支持纯C、增加CPUF常数、x86平台判断。
一、更新说明
1.1 支持Mac OS X平台
之前我发现了Mac OS X中的“/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/4.0/include”目录中有intrin头文件(http://www.cnblogs.com/zyl910/archive/2012/09/27/intrin_mac.html)。于是以为ccpuid不经过修改便能在Mac OS C中编译。但是实际测试时发现,gcc报告找不到“cpuid.h”。
但是很奇怪,“#include <xmmintrin.h>”却能正常包含。
虽然修改gcc的目录配置也许能解决问题,但我没有这么做,因为这样会增加配置成本。
而且,打开Mac OS X中的cpuid.h一看,发现它没有定义__cpuid/__cpuid_count等宏。也就是说,就算正确包含了cpuid.h,也因缺少相关宏而报错。
换一下思路,直接使用内嵌汇编行不行呢?
VC中的内嵌汇编不支持64位,于是只有使用intrin函数。而gcc的内嵌汇编不受该限制,64位下也可使用内嵌汇编,例如Fedora的cpuid.h中就是用内嵌汇编实现__cpuid等宏的。
Mac下的gcc也是一种gcc,内嵌汇编的语法应该是一样的。
于是我试着将Fedora的cpuid.h中关于__cpuid等宏的的代码,用Mac下的gcc编译。果然编译成功,运行正常。
__cpuid的相关代码修改成——
#include <xmmintrin.h> // MMX, SSE //#include <cpuid.h> // mac 中的 llvm-gcc有时找不到cpuid.h,而且它没有 __cpuid/__cpuid_count,干脆我们自己定义. #ifndef __cpuid_count // 下面代码出自 GCC 4.7.0(Fedora 17) 的 cpuid.h #if defined(__i386__) && defined(__PIC__) /* %ebx may be the PIC register. */ #if __GNUC__ >= 3 #define __cpuid(level, a, b, c, d) \ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ "cpuid\n\t" \ "xchg{l}\t{%%}ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ "cpuid\n\t" \ "xchg{l}\t{%%}ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #else /* Host GCCs older than 3.0 weren't supporting Intel asm syntax nor alternatives in i386 code. */ #define __cpuid(level, a, b, c, d) \ __asm__ ("xchgl\t%%ebx, %1\n\t" \ "cpuid\n\t" \ "xchgl\t%%ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("xchgl\t%%ebx, %1\n\t" \ "cpuid\n\t" \ "xchgl\t%%ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #endif #else #define __cpuid(level, a, b, c, d) \ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #endif #endif // #ifndef __cpuid_count
1.2 支持纯C
ccpuid最初为了使用方便,于是将其封装成类,使得只有C++程序才能使用该模块,而纯C程序不能使用。
现在决定将其拆分为纯C版和C++版,使纯C程序也能使用。
具体做法是——
1. 将原 ccpuid.h 拆分为 ccpuid.h 与 ccpuid.hpp。纯C的依然保留在ccpuid.h,而C++部分移至ccpuid.hpp。
2. ccpuid.cpp中的全局函数移至ccpuid.h,并作为内联函数。
3. 因纯C不支持结构化异常处理, 忽略simd_mmx、simd_sse_level的 操作系统判断。
使用方法——
1. 对于纯C程序:只需引入ccpuid.h这个头文件就行了。
2. 对于C++程序:引入ccpuid.hpp,并在项目中加上ccpuid.cpp这个源文件一起编译。
注意为了避免全局变量问题,CPUFDesc、SseNames等数组仍是作为CCPUID类的静态成员,所以它们只能在C++版中使用。
1.3 增加CPUF常数
根据最新的Intel文档——
《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 3A, 3B, and 3C》044US. August 2012. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
《Intel® Architecture Instruction Set Extensions Programming Reference》014. AUGUST 2012. http://software.intel.com/en-us/avx/
《Intel® Processor Identification and the CPUID Instruction》. May 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
增加了这些CPUF常数——
CPUID.(EAX=07H, ECX=0H):EBX.TSC_ADJUST(bit 1). // IA32_TSC_ADJUST MSR is supported if 1.
CPUID.(EAX=07H, ECX=0H):EBX.RDSEED(bit 18) // RDSEED instruction.
CPUID.(EAX=07H, ECX=0H):EBX.ADX(bit 19) // ADCX and ADOX instructions.
CPUID.(EAX=07H, ECX=0H):EBX.SMAP(bit 20) // Supervisor Mode Access Prevention.
1.4 x86平台判断
以前没有考虑平台检查,在非x86平台上编译时会报错。于是在V1.02版中加入了平台判断,在非x86平台上返回0而不是无法编译。
判断x86平台的具体做法是——
1. 对于GCC:判断 __i386__ 或 __x86_64__ 宏是否存在。
2. 对于VC:判断 _M_IX86 或 _M_X64 宏是否存在。
然后根据上面的判断结果定义CCPUID_X86宏。在simd_mmx等函数中就可以利用CCPUID_X86宏来避免编译出错。
这样做的有利于代码的移植。例如某个程序使用了ccpuid来判断CPU是否支持SSE,在x86平台上可以正常检查,而在非x86平台上能返回0表示不支持,使得后续的SSE代码不会在非x86平台上运行。
二、全部代码
2.1 ccpuid.h: CPUID信息(纯C版)
全部代码——
#ifndef __CCPUID_H_INCLUDED #define __CCPUID_H_INCLUDED #include <stddef.h> // NULL等标准宏和类型. // 统一使用“uint32_t” //#include <basetsd.h> // INT32、UINT32等规范类型名. #include "stdint.h" // intrinsics #if (defined(__GNUC__)) // GCC #if (defined(__i386__) || defined(__x86_64__)) #define CCPUID_X86 1 // 是x86平台. #include <xmmintrin.h> // MMX, SSE //#include <cpuid.h> // mac 中的 llvm-gcc有时找不到cpuid.h,而且它没有 __cpuid/__cpuid_count,干脆我们自己定义. #ifndef __cpuid_count // 下面代码出自 GCC 4.7.0(Fedora 17) 的 cpuid.h #if defined(__i386__) && defined(__PIC__) /* %ebx may be the PIC register. */ #if __GNUC__ >= 3 #define __cpuid(level, a, b, c, d) \ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ "cpuid\n\t" \ "xchg{l}\t{%%}ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ "cpuid\n\t" \ "xchg{l}\t{%%}ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #else /* Host GCCs older than 3.0 weren't supporting Intel asm syntax nor alternatives in i386 code. */ #define __cpuid(level, a, b, c, d) \ __asm__ ("xchgl\t%%ebx, %1\n\t" \ "cpuid\n\t" \ "xchgl\t%%ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("xchgl\t%%ebx, %1\n\t" \ "cpuid\n\t" \ "xchgl\t%%ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #endif #else #define __cpuid(level, a, b, c, d) \ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level)) #define __cpuid_count(level, count, a, b, c, d) \ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) #endif #endif // #ifndef __cpuid_count #endif // #if (defined(__i386__) || defined(__x86_64__) ) #elif defined(_MSC_VER) // MSVC #if (defined(_M_IX86) || defined(_M_X64)) #define CCPUID_X86 1 // 是x86平台. #if _MSC_VER >=1400 // VC2005 #include <intrin.h> // CPUID, MMX, SSE #elif _MSC_VER >=1200 // VC6 #include <xmmintrin.h> // MMX, SSE #endif // #if _MSC_VER >=1400 #endif #else #error Only supports MSVC or GCC. #endif // #if defined(__GNUC__) // INLINE #ifndef INLINE #if defined(_MSC_VER) // MSVC #define INLINE __inline #else // C99 #define INLINE inline #endif #endif #if defined __cplusplus extern "C" { #endif //////////////////////////////////////// // getcpuid: 获取CPUID信息的基础函数. //////////////////////////////////////// INLINE void getcpuidex(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue) { if (NULL==CPUInfo) return; #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) // GCC __cpuid_count(InfoType, ECXValue, CPUInfo[0],CPUInfo[1],CPUInfo[2],CPUInfo[3]); #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) // MSVC #if defined(_M_X64) || _MSC_VER>=1600 // 64位下不支持内联汇编. 1600: VS2010, 据说VC2008 SP1之后才支持__cpuidex. __cpuidex((int*)CPUInfo, (int)InfoType, (int)ECXValue); #else _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 #else // 不支持,返回0 . CPUInfo[0] = CPUInfo[1] = CPUInfo[2] = CPUInfo[3] = 0; #endif // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) } INLINE void getcpuid(uint32_t CPUInfo[4], uint32_t InfoType) { #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) // GCC __cpuid(InfoType, CPUInfo[0],CPUInfo[1],CPUInfo[2],CPUInfo[3]); #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) // MSVC #if _MSC_VER>=1400 // VC2005才支持__cpuid __cpuid((int*)CPUInfo, (int)InfoType); #else getcpuidex(CPUInfo, InfoType, 0); #endif #else getcpuidex(CPUInfo, InfoType, 0); #endif // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) } // 存储单条CPUID信息的结构体. typedef struct tagCPUIDINFO{ uint32_t fid; // 功能号. 即CPUID指令的EAX参数. uint32_t fidsub; // 子功能号. 即CPUID指令的ECX参数. union{ uint32_t dw[4]; // 返回的信息. struct{ uint32_t _eax; uint32_t _ebx; uint32_t _ecx; uint32_t _edx; }; }; }CPUIDINFO, *LPCPUIDINFO; typedef const CPUIDINFO* LPCCPUIDINFO; //////////////////////////////////////// // CPUIDFIELD: CPUID字段的统一编号方案. // // http://www.cnblogs.com/zyl910/archive/2012/06/29/getcpuidfield.html //////////////////////////////////////// typedef uint32_t CPUIDFIELD; #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)&0xF0000000U) \ | ((fid)<<CPUIDFIELD_SHIFT_FID & 0x0FF00000) \ | ((fidsub)<<CPUIDFIELD_SHIFT_FIDSUB & CPUIDFIELD_MASK_FIDSUB) \ | ((reg)<<CPUIDFIELD_SHIFT_REG & CPUIDFIELD_MASK_REG) \ | ((pos)<<CPUIDFIELD_SHIFT_POS & CPUIDFIELD_MASK_POS) \ | (((len)-1)<<CPUIDFIELD_SHIFT_LEN & CPUIDFIELD_MASK_LEN) \ ) #define CPUIDFIELD_FID(cpuidfield) ( ((uint32_t)(cpuidfield)&0xF0000000U) | (((uint32_t)(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 ) // CPUID字段的描述. typedef struct tagCPUIDFIELDDESC{ CPUIDFIELD cpuf; int reserved; const char* szName; const char* szDesc; }CPUIDFIELDDESC, *LPCPUIDFIELDDESC; typedef const CPUIDFIELDDESC* LPCCPUIDFIELDDESC; #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_CX16 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_TSC_ADJUST CPUIDFIELD_MAKE(7,0,1,1,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_RDSEED CPUIDFIELD_MAKE(7,0,1,18,1) #define CPUF_ADX CPUIDFIELD_MAKE(7,0,1,19,1) #define CPUF_SMAP CPUIDFIELD_MAKE(7,0,1,20,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(0x80000000U,0,0,0,32) #define CPUF_BrandId16 CPUIDFIELD_MAKE(0x80000001U,0,1,0,16) #define CPUF_PkgType CPUIDFIELD_MAKE(0x80000001U,0,1,28,4) #define CPUF_LahfSahf CPUIDFIELD_MAKE(0x80000001U,0,2,0,1) #define CPUF_CmpLegacy CPUIDFIELD_MAKE(0x80000001U,0,2,1,1) #define CPUF_SVM CPUIDFIELD_MAKE(0x80000001U,0,2,2,1) #define CPUF_ExtApicSpace CPUIDFIELD_MAKE(0x80000001U,0,2,3,1) #define CPUF_AltMovCr8 CPUIDFIELD_MAKE(0x80000001U,0,2,4,1) #define CPUF_ABM CPUIDFIELD_MAKE(0x80000001U,0,2,5,1) #define CPUF_SSE4A CPUIDFIELD_MAKE(0x80000001U,0,2,6,1) #define CPUF_MisAlignSse CPUIDFIELD_MAKE(0x80000001U,0,2,7,1) #define CPUF_3DNowPrefetch CPUIDFIELD_MAKE(0x80000001U,0,2,8,1) #define CPUF_OSVW CPUIDFIELD_MAKE(0x80000001U,0,2,9,1) #define CPUF_IBS CPUIDFIELD_MAKE(0x80000001U,0,2,10,1) #define CPUF_XOP CPUIDFIELD_MAKE(0x80000001U,0,2,11,1) #define CPUF_SKINIT CPUIDFIELD_MAKE(0x80000001U,0,2,12,1) #define CPUF_WDT CPUIDFIELD_MAKE(0x80000001U,0,2,13,1) #define CPUF_LWP CPUIDFIELD_MAKE(0x80000001U,0,2,15,1) #define CPUF_FMA4 CPUIDFIELD_MAKE(0x80000001U,0,2,16,1) #define CPUF_BIT_NODEID CPUIDFIELD_MAKE(0x80000001U,0,2,19,1) #define CPUF_TBM CPUIDFIELD_MAKE(0x80000001U,0,2,21,1) #define CPUF_TopologyExtensions CPUIDFIELD_MAKE(0x80000001U,0,2,22,1) #define CPUF_SYSCALL CPUIDFIELD_MAKE(0x80000001U,0,3,11,1) #define CPUF_XD CPUIDFIELD_MAKE(0x80000001U,0,3,20,1) #define CPUF_MmxExt CPUIDFIELD_MAKE(0x80000001U,0,3,22,1) #define CPUF_FFXSR CPUIDFIELD_MAKE(0x80000001U,0,3,25,1) #define CPUF_Page1GB CPUIDFIELD_MAKE(0x80000001U,0,3,26,1) #define CPUF_RDTSCP CPUIDFIELD_MAKE(0x80000001U,0,3,27,1) #define CPUF_LM CPUIDFIELD_MAKE(0x80000001U,0,3,29,1) #define CPUF_3DNowExt CPUIDFIELD_MAKE(0x80000001U,0,3,30,1) #define CPUF_3DNow CPUIDFIELD_MAKE(0x80000001U,0,3,31,1) #define CPUF_L1ITlb2and4MSize CPUIDFIELD_MAKE(0x80000005U,0,0,0,8) #define CPUF_L1ITlb2and4MAssoc CPUIDFIELD_MAKE(0x80000005U,0,0,8,8) #define CPUF_L1DTlb2and4MSize CPUIDFIELD_MAKE(0x80000005U,0,0,16,8) #define CPUF_L1DTlb2and4MAssoc CPUIDFIELD_MAKE(0x80000005U,0,0,24,8) #define CPUF_L1ITlb4KSize CPUIDFIELD_MAKE(0x80000005U,0,1,0,8) #define CPUF_L1ITlb4KAssoc CPUIDFIELD_MAKE(0x80000005U,0,1,8,8) #define CPUF_L1DTlb4KSize CPUIDFIELD_MAKE(0x80000005U,0,1,16,8) #define CPUF_L1DTlb4KAssoc CPUIDFIELD_MAKE(0x80000005U,0,1,24,8) #define CPUF_L1DcLineSize CPUIDFIELD_MAKE(0x80000005U,0,2,0,8) #define CPUF_L1DcLinesPerTag CPUIDFIELD_MAKE(0x80000005U,0,2,8,8) #define CPUF_L1DcAssoc CPUIDFIELD_MAKE(0x80000005U,0,2,16,8) #define CPUF_L1DcSize CPUIDFIELD_MAKE(0x80000005U,0,2,24,8) #define CPUF_L1IcLineSize CPUIDFIELD_MAKE(0x80000005U,0,3,0,8) #define CPUF_L1IcLinesPerTag CPUIDFIELD_MAKE(0x80000005U,0,3,8,8) #define CPUF_L1IcAssoc CPUIDFIELD_MAKE(0x80000005U,0,3,16,8) #define CPUF_L1IcSize CPUIDFIELD_MAKE(0x80000005U,0,3,24,8) #define CPUF_L2ITlb2and4MSize CPUIDFIELD_MAKE(0x80000006U,0,0,0,12) #define CPUF_L2ITlb2and4MAssoc CPUIDFIELD_MAKE(0x80000006U,0,0,12,4) #define CPUF_L2DTlb2and4MSize CPUIDFIELD_MAKE(0x80000006U,0,0,16,12) #define CPUF_L2DTlb2and4MAssoc CPUIDFIELD_MAKE(0x80000006U,0,0,28,4) #define CPUF_L2ITlb4KSize CPUIDFIELD_MAKE(0x80000006U,0,1,0,12) #define CPUF_L2ITlb4KAssoc CPUIDFIELD_MAKE(0x80000006U,0,1,12,4) #define CPUF_L2DTlb4KSize CPUIDFIELD_MAKE(0x80000006U,0,1,16,12) #define CPUF_L2DTlb4KAssoc CPUIDFIELD_MAKE(0x80000006U,0,1,28,4) #define CPUF_L2LineSize CPUIDFIELD_MAKE(0x80000006U,0,2,0,8) #define CPUF_L2LinesPerTag CPUIDFIELD_MAKE(0x80000006U,0,2,8,4) #define CPUF_L2Assoc CPUIDFIELD_MAKE(0x80000006U,0,2,12,4) #define CPUF_L2Size CPUIDFIELD_MAKE(0x80000006U,0,2,16,16) #define CPUF_L3LineSize CPUIDFIELD_MAKE(0x80000006U,0,3,0,8) #define CPUF_L3LinesPerTag CPUIDFIELD_MAKE(0x80000006U,0,3,8,4) #define CPUF_L3Assoc CPUIDFIELD_MAKE(0x80000006U,0,3,12,4) #define CPUF_L3Size CPUIDFIELD_MAKE(0x80000006U,0,3,18,14) #define CPUF_TS CPUIDFIELD_MAKE(0x80000007U,0,3,0,1) #define CPUF_FID CPUIDFIELD_MAKE(0x80000007U,0,3,1,1) #define CPUF_VID CPUIDFIELD_MAKE(0x80000007U,0,3,2,1) #define CPUF_TTP CPUIDFIELD_MAKE(0x80000007U,0,3,3,1) #define CPUF_HTC CPUIDFIELD_MAKE(0x80000007U,0,3,4,1) #define CPUF_100MHzSteps CPUIDFIELD_MAKE(0x80000007U,0,3,6,1) #define CPUF_HwPstate CPUIDFIELD_MAKE(0x80000007U,0,3,7,1) #define CPUF_TscInvariant CPUIDFIELD_MAKE(0x80000007U,0,3,8,1) #define CPUF_CPB CPUIDFIELD_MAKE(0x80000007U,0,3,9,1) #define CPUF_EffFreqRO CPUIDFIELD_MAKE(0x80000007U,0,3,10,1) #define CPUF_PhysAddrSize CPUIDFIELD_MAKE(0x80000008U,0,0,0,8) #define CPUF_LinAddrSize CPUIDFIELD_MAKE(0x80000008U,0,0,8,8) #define CPUF_GuestPhysAddrSize CPUIDFIELD_MAKE(0x80000008U,0,0,16,8) #define CPUF_NC CPUIDFIELD_MAKE(0x80000008U,0,2,0,8) #define CPUF_ApicIdCoreIdSize CPUIDFIELD_MAKE(0x80000008U,0,2,12,4) #define CPUF_SvmRev CPUIDFIELD_MAKE(0x8000000AU,0,0,0,8) #define CPUF_NASID CPUIDFIELD_MAKE(0x8000000AU,0,1,0,32) #define CPUF_NP CPUIDFIELD_MAKE(0x8000000AU,0,3,0,1) #define CPUF_LbrVirt CPUIDFIELD_MAKE(0x8000000AU,0,3,1,1) #define CPUF_SVML CPUIDFIELD_MAKE(0x8000000AU,0,3,2,1) #define CPUF_NRIPS CPUIDFIELD_MAKE(0x8000000AU,0,3,3,1) #define CPUF_TscRateMsr CPUIDFIELD_MAKE(0x8000000AU,0,3,4,1) #define CPUF_VmcbClean CPUIDFIELD_MAKE(0x8000000AU,0,3,5,1) #define CPUF_FlushByAsid CPUIDFIELD_MAKE(0x8000000AU,0,3,6,1) #define CPUF_DecodeAssists CPUIDFIELD_MAKE(0x8000000AU,0,3,7,1) #define CPUF_PauseFilter CPUIDFIELD_MAKE(0x8000000AU,0,3,10,1) #define CPUF_PauseFilterThreshold CPUIDFIELD_MAKE(0x8000000AU,0,3,12,1) #define CPUF_L1ITlb1GSize CPUIDFIELD_MAKE(0x80000019U,0,0,0,12) #define CPUF_L1ITlb1GAssoc CPUIDFIELD_MAKE(0x80000019U,0,0,12,4) #define CPUF_L1DTlb1GSize CPUIDFIELD_MAKE(0x80000019U,0,0,16,12) #define CPUF_L1DTlb1GAssoc CPUIDFIELD_MAKE(0x80000019U,0,0,28,4) #define CPUF_L2ITlb1GSize CPUIDFIELD_MAKE(0x80000019U,0,1,0,12) #define CPUF_L2ITlb1GAssoc CPUIDFIELD_MAKE(0x80000019U,0,1,12,4) #define CPUF_L2DTlb1GSize CPUIDFIELD_MAKE(0x80000019U,0,1,16,12) #define CPUF_L2DTlb1GAssoc CPUIDFIELD_MAKE(0x80000019U,0,1,28,4) #define CPUF_FP128 CPUIDFIELD_MAKE(0x8000001AU,0,0,0,1) #define CPUF_MOVU CPUIDFIELD_MAKE(0x8000001AU,0,0,1,1) #define CPUF_IBSFFV CPUIDFIELD_MAKE(0x8000001BU,0,0,0,1) #define CPUF_FetchSam CPUIDFIELD_MAKE(0x8000001BU,0,0,1,1) #define CPUF_OpSam CPUIDFIELD_MAKE(0x8000001BU,0,0,2,1) #define CPUF_RdWrOpCnt CPUIDFIELD_MAKE(0x8000001BU,0,0,3,1) #define CPUF_OpCnt CPUIDFIELD_MAKE(0x8000001BU,0,0,4,1) #define CPUF_BrnTrgt CPUIDFIELD_MAKE(0x8000001BU,0,0,5,1) #define CPUF_OpCntExt CPUIDFIELD_MAKE(0x8000001BU,0,0,6,1) #define CPUF_RipInvalidChk CPUIDFIELD_MAKE(0x8000001BU,0,0,7,1) #define CPUF_LwpAvail CPUIDFIELD_MAKE(0x8000001CU,0,0,0,1) #define CPUF_LwpVAL CPUIDFIELD_MAKE(0x8000001CU,0,0,1,1) #define CPUF_LwpIRE CPUIDFIELD_MAKE(0x8000001CU,0,0,2,1) #define CPUF_LwpBRE CPUIDFIELD_MAKE(0x8000001CU,0,0,3,1) #define CPUF_LwpDME CPUIDFIELD_MAKE(0x8000001CU,0,0,4,1) #define CPUF_LwpCNH CPUIDFIELD_MAKE(0x8000001CU,0,0,5,1) #define CPUF_LwpRNH CPUIDFIELD_MAKE(0x8000001CU,0,0,6,1) #define CPUF_LwpInt CPUIDFIELD_MAKE(0x8000001CU,0,0,31,1) #define CPUF_LwpCbSize CPUIDFIELD_MAKE(0x8000001CU,0,1,0,8) #define CPUF_LwpEventSize CPUIDFIELD_MAKE(0x8000001CU,0,1,8,8) #define CPUF_LwpMaxEvents CPUIDFIELD_MAKE(0x8000001CU,0,1,16,8) #define CPUF_LwpEventOffset CPUIDFIELD_MAKE(0x8000001CU,0,1,24,8) #define CPUF_LwpLatencyMax CPUIDFIELD_MAKE(0x8000001CU,0,2,0,5) #define CPUF_LwpDataAddress CPUIDFIELD_MAKE(0x8000001CU,0,2,5,1) #define CPUF_LwpLatencyRnd CPUIDFIELD_MAKE(0x8000001CU,0,2,6,3) #define CPUF_LwpVersion CPUIDFIELD_MAKE(0x8000001CU,0,2,9,7) #define CPUF_LwpMinBufferSize CPUIDFIELD_MAKE(0x8000001CU,0,2,16,8) #define CPUF_LwpBranchPrediction CPUIDFIELD_MAKE(0x8000001CU,0,2,28,1) #define CPUF_LwpIpFiltering CPUIDFIELD_MAKE(0x8000001CU,0,2,29,1) #define CPUF_LwpCacheLevels CPUIDFIELD_MAKE(0x8000001CU,0,2,30,1) #define CPUF_LwpCacheLatency CPUIDFIELD_MAKE(0x8000001CU,0,2,31,1) #define CPUF_D_LwpAvail CPUIDFIELD_MAKE(0x8000001CU,0,3,0,1) #define CPUF_D_LwpVAL CPUIDFIELD_MAKE(0x8000001CU,0,3,1,1) #define CPUF_D_LwpIRE CPUIDFIELD_MAKE(0x8000001CU,0,3,2,1) #define CPUF_D_LwpBRE CPUIDFIELD_MAKE(0x8000001CU,0,3,3,1) #define CPUF_D_LwpDME CPUIDFIELD_MAKE(0x8000001CU,0,3,4,1) #define CPUF_D_LwpCNH CPUIDFIELD_MAKE(0x8000001CU,0,3,5,1) #define CPUF_D_LwpRNH CPUIDFIELD_MAKE(0x8000001CU,0,3,6,1) #define CPUF_D_LwpInt CPUIDFIELD_MAKE(0x8000001CU,0,3,31,1) #define CPUF_CacheType CPUIDFIELD_MAKE(0x8000001DU,0,0,0,5) #define CPUF_CacheLevel CPUIDFIELD_MAKE(0x8000001DU,0,0,5,3) #define CPUF_SelfInitialization CPUIDFIELD_MAKE(0x8000001DU,0,0,8,1) #define CPUF_FullyAssociative CPUIDFIELD_MAKE(0x8000001DU,0,0,9,1) #define CPUF_NumSharingCache CPUIDFIELD_MAKE(0x8000001DU,0,0,14,12) #define CPUF_CacheLineSize CPUIDFIELD_MAKE(0x8000001DU,0,1,0,12) #define CPUF_CachePhysPartitions CPUIDFIELD_MAKE(0x8000001DU,0,1,12,10) #define CPUF_CacheNumWays CPUIDFIELD_MAKE(0x8000001DU,0,1,22,10) #define CPUF_CacheNumSets CPUIDFIELD_MAKE(0x8000001DU,0,2,0,32) #define CPUF_WBINVD CPUIDFIELD_MAKE(0x8000001DU,0,3,0,1) #define CPUF_CacheInclusive CPUIDFIELD_MAKE(0x8000001DU,0,3,1,1) #define CPUF_ExtendedApicId CPUIDFIELD_MAKE(0x8000001EU,0,0,0,32) #define CPUF_ComputeUnitId CPUIDFIELD_MAKE(0x8000001EU,0,1,0,8) #define CPUF_CoresPerComputeUnit CPUIDFIELD_MAKE(0x8000001EU,0,1,8,2) #define CPUF_NodeId CPUIDFIELD_MAKE(0x8000001EU,0,2,0,8) #define CPUF_NodesPerProcessor CPUIDFIELD_MAKE(0x8000001EU,0,2,8,3) // 取得位域. #ifndef __GETBITS32 #define __GETBITS32(src,pos,len) ( ((src)>>(pos)) & (((uint32_t)-1)>>(32-len)) ) #endif // 根据CPUIDFIELD从缓冲区中获取字段. INLINE uint32_t getcpuidfield_buf(const uint32_t dwBuf[4], CPUIDFIELD cpuf) { return __GETBITS32(dwBuf[CPUIDFIELD_REG(cpuf)], CPUIDFIELD_POS(cpuf), CPUIDFIELD_LEN(cpuf)); } // 根据CPUIDFIELD获取CPUID字段. INLINE uint32_t getcpuidfield(CPUIDFIELD cpuf) { uint32_t dwBuf[4]; getcpuidex(dwBuf, CPUIDFIELD_FID(cpuf), CPUIDFIELD_FIDSUB(cpuf)); return getcpuidfield_buf(dwBuf, cpuf); } //////////////////////////////////////// // functions: 函数. //////////////////////////////////////// // 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 declaration //int cpu_getvendor(char* pvendor); //int cpu_getbrand(char* pbrand); //int simd_mmx(int* phwmmx); //int simd_sse_level(int* phwsse); //int simd_avx_level(int* phwavx); // 取得CPU厂商(Vendor). // // result: 成功时返回字符串的长度(一般为12)。失败时返回0. // pvendor: 接收厂商信息的字符串缓冲区。至少为13字节. INLINE int cpu_getvendor(char* pvendor) { uint32_t dwBuf[4]; if (NULL==pvendor) return 0; // Function 0: Vendor-ID and Largest Standard Function getcpuid(dwBuf, 0); // save. 保存到pvendor *(uint32_t *)&pvendor[0] = dwBuf[1]; // ebx: 前四个字符. *(uint32_t *)&pvendor[4] = dwBuf[3]; // edx: 中间四个字符. *(uint32_t *)&pvendor[8] = dwBuf[2]; // ecx: 最后四个字符. pvendor[12] = '\0'; return 12; } // 取得CPU商标(Brand). // // result: 成功时返回字符串的长度(一般为48)。失败时返回0. // pbrand: 接收商标信息的字符串缓冲区。至少为49字节. INLINE int cpu_getbrand(char* pbrand) { uint32_t dwBuf[4]; if (NULL==pbrand) return 0; // Function 0x80000000: Largest Extended Function Number getcpuid(dwBuf, 0x80000000U); if (dwBuf[0] < 0x80000004U) return 0; // Function 80000002h,80000003h,80000004h: Processor Brand String getcpuid((uint32_t *)&pbrand[0], 0x80000002U); // 前16个字符. getcpuid((uint32_t *)&pbrand[16], 0x80000003U); // 中间16个字符. getcpuid((uint32_t *)&pbrand[32], 0x80000004U); // 最后16个字符. pbrand[48] = '\0'; return 48; } // 是否支持MMX指令集. // // result: 返回操作系统是否支持MMX指令集. 非0表示支持, 0表示不支持. // phwmmx: 返回硬件是否支持MMX指令集. 非0表示支持, 0表示不支持. INLINE int simd_mmx(int* phwmmx) { int rt = 0; // result #ifdef CCPUID_X86 const uint32_t BIT_D_MMX = 0x00800000; // bit 23 uint32_t dwBuf[4]; // check processor support getcpuid(dwBuf, 1); // Function 1: Feature Information if ( dwBuf[3] & BIT_D_MMX ) rt=1; if (NULL!=phwmmx) *phwmmx=rt; // check OS support // 纯C不支持结构化异常处理, 忽略simd_mmx、simd_sse_level的 操作系统判断. #if defined(__cplusplus) if ( rt ) { #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) // VC编译器不支持64位下的MMX. rt=0; #else try { _mm_empty(); // MMX instruction: emms } catch(...) { rt=0; } #endif // #if defined(_M_X64) && defined(_MSC_VER) } #endif // #if defined(__cplusplus) #else // #ifdef CCPUID_X86 if (NULL!=phwmmx) *phwmmx=rt; #endif // #ifdef CCPUID_X86 return rt; } // 检测SSE系列指令集的支持级别. // // result: 返回操作系统的SSE系列指令集支持级别. 详见SIMD_SSE_常数. // phwmmx: 返回硬件的SSE系列指令集支持级别. 详见SIMD_SSE_常数. INLINE int simd_sse_level(int* phwsse) { int rt = SIMD_SSE_NONE; // result #ifdef CCPUID_X86 const uint32_t BIT_D_SSE = 0x02000000; // bit 25 const uint32_t BIT_D_SSE2 = 0x04000000; // bit 26 const uint32_t BIT_C_SSE3 = 0x00000001; // bit 0 const uint32_t BIT_C_SSSE3 = 0x00000100; // bit 9 const uint32_t BIT_C_SSE41 = 0x00080000; // bit 19 const uint32_t BIT_C_SSE42 = 0x00100000; // bit 20 uint32_t dwBuf[4]; // check processor support getcpuid(dwBuf, 1); // Function 1: Feature Information if ( dwBuf[3] & BIT_D_SSE ) { rt = SIMD_SSE_1; if ( dwBuf[3] & BIT_D_SSE2 ) { rt = SIMD_SSE_2; if ( dwBuf[2] & BIT_C_SSE3 ) { rt = SIMD_SSE_3; if ( dwBuf[2] & BIT_C_SSSE3 ) { rt = SIMD_SSE_3S; if ( dwBuf[2] & BIT_C_SSE41 ) { rt = SIMD_SSE_41; if ( dwBuf[2] & BIT_C_SSE42 ) { rt = SIMD_SSE_42; } } } } } } if (NULL!=phwsse) *phwsse=rt; // check OS support // 纯C不支持结构化异常处理, 忽略simd_mmx、simd_sse_level的 操作系统判断. #if defined(__cplusplus) try { __m128 xmm1 = _mm_setzero_ps(); // SSE instruction: xorps int* pxmm1 = (int*)&xmm1; // 避免GCC的 -Wstrict-aliasing 警告. if (0!=*pxmm1) rt = SIMD_SSE_NONE; // 避免Release模式编译优化时剔除_mm_setzero_ps. } catch(...) { rt = SIMD_SSE_NONE; } #endif // #if defined(__cplusplus) #else // #ifdef CCPUID_X86 if (NULL!=phwsse) *phwsse=rt; #endif // #ifdef CCPUID_X86 return rt; } // 检测AVX系列指令集的支持级别. // // result: 返回操作系统的AVX系列指令集支持级别. 详见SIMD_AVX_常数. // phwavx: 返回硬件的AVX系列指令集支持级别. 详见SIMD_AVX_常数. INLINE int simd_avx_level(int* phwavx) { int rt = SIMD_AVX_NONE; // result #ifdef CCPUID_X86 // check processor support if (0!=getcpuidfield(CPUF_AVX)) { rt = SIMD_AVX_1; if (0!=getcpuidfield(CPUF_AVX2)) { rt = SIMD_AVX_2; } } if (NULL!=phwavx) *phwavx=rt; // check OS support if (0!=getcpuidfield(CPUF_OSXSAVE)) // XGETBV enabled for application use. { uint32_t n = getcpuidfield(CPUF_XFeatureSupportedMaskLo); // XCR0: XFeatureSupportedMask register. if (6!=(n&6)) // XCR0[2:1] = ‘11b’ (XMM state and YMM state are enabled by OS). { rt = SIMD_AVX_NONE; } } #else // #ifdef CCPUID_X86 if (NULL!=phwavx) *phwavx=rt; #endif // #ifdef CCPUID_X86 return rt; } #if defined __cplusplus }; #endif #endif // #ifndef __CCPUID_H_INCLUDED
2.2 testccpuidc.c : [C] 测试ccpuid.h, 显示CPUID信息
全部代码——
#include <stdio.h> #include "ccpuid.h" // 获取程序位数(被编译为多少位的代码) int GetProgramBits() { return sizeof(int*) * 8; } int main(int argc, char* argv[]) { char szBuf[64]; int bhwmmx; // 硬件支持MMX. int bmmx; // 操作系统支持MMX. int nhwsse; // 硬件支持SSE. int nsse; // 操作系统支持SSE. int nhwavx; // 硬件支持AVX. int navx; // 操作系统支持AVX. printf("testccpuidc v1.02 (%dbit)\n\n", GetProgramBits()); // base cpu_getvendor(szBuf); printf("CPU Vendor:\t%s\n", szBuf); cpu_getbrand(szBuf); printf("CPU Brand:\t%s\n", szBuf); printf("LFuncStd:\t%.8Xh\n", getcpuidfield(CPUF_LFuncStd)); printf("LFuncExt:\t%.8Xh\n", getcpuidfield(CPUF_LFuncExt)); // mmx bmmx = simd_mmx(&bhwmmx); printf("MMX: %d\t// hw: %d\n", bmmx, bhwmmx); // sse nsse = simd_sse_level(&nhwsse); printf("SSE: %d\t// hw: %d\n", nsse, nhwsse); // avx navx = simd_avx_level(&nhwavx); printf("AVX: %d\t// hw: %d\n", navx, nhwavx); // misc printf("SSE4A:\t%d\n", getcpuidfield(CPUF_SSE4A)); printf("AES:\t%d\n", getcpuidfield(CPUF_AES)); printf("PCLMULQDQ:\t%d\n", getcpuidfield(CPUF_PCLMULQDQ)); printf("F16C:\t%d\n", getcpuidfield(CPUF_F16C)); printf("FMA:\t%d\n", getcpuidfield(CPUF_FMA)); printf("FMA4:\t%d\n", getcpuidfield(CPUF_FMA4)); printf("XOP:\t%d\n", getcpuidfield(CPUF_XOP)); return 0; }
2.3 ccpuid.hpp: CPUID信息(C++版头文件)
全部代码——
#ifndef __CCPUID_HPP_INCLUDED #define __CCPUID_HPP_INCLUDED #include "ccpuid.h" //////////////////////////////////////// // define struct //////////////////////////////////////// #if defined __cplusplus extern "C" { #endif #define MAX_CPUIDINFO 0x100 // CCPUID类中最多保存多少条CPUIDINFO信息。 #if defined __cplusplus }; #endif //////////////////////////////////////// // define class //////////////////////////////////////// // CPUID工具类. class CCPUID{ public: enum { CPUFDescLen = 296 // CPUIDFIELD描述信息数组的长度. }; static const CPUIDFIELDDESC CPUFDesc[CPUFDescLen]; // CPUIDFIELD描述信息数组. static const char* CacheDesc[0x100]; // 缓存描述信息数组. static const char* SseNames[7]; // SSE级别的名称. static const char* AvxNames[3]; // AVX级别的名称. CPUIDINFO Info[MAX_CPUIDINFO+1]; // CPUID信息数组. CCPUID(); static CCPUID& cur() { if(0==_cur._InfoCount){ _cur.RefreshAll(); } return _cur; } // 当前处理器的CCPUID. int InfoCount() const { return _InfoCount; } // Info数组的有效项目数. void RefreshInfo(); // 刷新信息. void RefreshProperty(); // 刷新属性. void RefreshAll(); // 刷新所有. LPCCPUIDINFO GetInfo(uint32_t InfoType, uint32_t ECXValue=0) const; // 取得信息. void GetData(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue=0) const; // 取得数据. uint32_t GetField(CPUIDFIELD cpuf) const; // 取得CPUID字段 // Property uint32_t LFuncStd() const { return _LFuncStd; } // 最大的主功能号. uint32_t LFuncExt() const { return _LFuncExt; } // 最大的扩展功能号. const char* Vendor() const { return _Vendor; } // 厂商. const char* Brand() const { return _Brand; } // 商标. const char* BrandTrim() const { return _BrandTrim; } // 去掉首都空格后的商标. int mmx() const { return _mmx; } // 系统支持MMX. int hwmmx() const { return _hwmmx; } // 硬件支持MMX. int sse() const { return _sse; } // 系统支持SSE. int hwsse() const { return _hwsse; } // 硬件支持SSE. int avx() const { return _avx; } // 系统支持AVX. int hwavx() const { return _hwavx; } // 硬件支持AVX. private: static CCPUID _cur; // 当前处理器的CCPUID. 为了方便日常使用. int _InfoCount; // Info数组的有效项目数. // Property uint32_t _LFuncStd; // 最大的主功能号. uint32_t _LFuncExt; // 最大的扩展功能号. char _Vendor[13]; // 厂商. char _Brand[49]; // 商标. const char* _BrandTrim; // 去掉首都空格后的商标. int _mmx; // 系统支持MMX. int _hwmmx; // 硬件支持MMX. int _sse; // 系统支持SSE. int _hwsse; // 硬件支持SSE. int _avx; // 系统支持AVX. int _hwavx; // 硬件支持AVX. void RefreshInfo_Put(uint32_t fid, uint32_t fidsub, uint32_t CPUInfo[4]); int simd_mmx(int* phwmmx) const; int simd_sse_level(int* phwsse) const; int simd_avx_level(int* phwavx) const; }; #endif // #ifndef __CCPUID_HPP_INCLUDED
2.4 ccpuid.cpp: CPUID信息(C++版源文件)
全部代码——
#include "ccpuid.hpp" CCPUID CCPUID::_cur; const CPUIDFIELDDESC CCPUID::CPUFDesc[] = { {CPUF_LFuncStd, 0, "LFuncStd", "largest standard function."} ,{CPUF_Stepping, 0, "Stepping", "processor stepping."} ,{CPUF_BaseModel, 0, "BaseModel", "base processor model."} ,{CPUF_BaseFamily, 0, "BaseFamily", "base processor family."} ,{CPUF_ProcessorType, 0, "ProcessorType", "processor type."} ,{CPUF_ExtModel, 0, "ExtModel", "processor extended model."} ,{CPUF_ExtFamily, 0, "ExtFamily", "processor extended family."} ,{CPUF_BrandId8, 0, "BrandId8", "8-bit brand ID."} ,{CPUF_CLFlush, 0, "CLFlush", "CLFLUSH line size. (*8)"} ,{CPUF_MaxApicId, 0, "MaxApicId", "Maximum number of addressable IDs for logical processors in this physical package."} ,{CPUF_ApicId, 0, "ApicId", "Initial local APIC physical ID(8-bit)."} ,{CPUF_SSE3, 0, "SSE3", "Streaming SIMD Extensions 3."} ,{CPUF_PCLMULQDQ, 0, "PCLMULQDQ", "PCLMULQDQ instruction."} ,{CPUF_DTES64, 0, "DTES64", "64-bit DS Area."} ,{CPUF_MONITOR, 0, "MONITOR", "MONITOR/MWAIT instructions."} ,{CPUF_DS_CPL, 0, "DS_CPL", "CPL Qualified Debug Store."} ,{CPUF_VMX, 0, "VMX", "Virtual Machine Extensions."} ,{CPUF_SMX, 0, "SMX", "Safer Mode Extensions."} ,{CPUF_EIST, 0, "EIST", "Enhanced Intel SpeedStep technology."} ,{CPUF_TM2, 0, "TM2", "Thermal Monitor 2."} ,{CPUF_SSSE3, 0, "SSSE3", "Supplemental Streaming SIMD Extensions 3 (SSSE3)."} ,{CPUF_CNXT_ID, 0, "CNXT_ID", "L1 Context ID."} ,{CPUF_FMA, 0, "FMA", "supports FMA extensions using YMM state."} ,{CPUF_CX16, 0, "CX16", "CMPXCHG16B instruction."} ,{CPUF_xTPR, 0, "xTPR", "xTPR Update Control. Can disable sending Task Priority messages."} ,{CPUF_PDCM, 0, "PDCM", "Perfmon and Debug Capability."} ,{CPUF_PCID, 0, "PCID", "Process Context Identifiers."} ,{CPUF_DCA, 0, "DCA", "Direct Cache Access."} ,{CPUF_SSE41, 0, "SSE41", "SSE4.1 instructions."} ,{CPUF_SSE42, 0, "SSE42", "SSE4.2 instructions."} ,{CPUF_x2APIC, 0, "x2APIC", "Extended xAPIC Support."} ,{CPUF_MOVBE, 0, "MOVBE", "MOVBE Instruction."} ,{CPUF_POPCNT, 0, "POPCNT", "POPCNT instruction."} ,{CPUF_TSC_DEADLINE, 0, "TSC_DEADLINE", "Local APIC timer supports one-shot operation using a TSC deadline value."} ,{CPUF_AES, 0, "AES", "Advanced Encryption Standard (AES) Instructions."} ,{CPUF_XSAVE, 0, "XSAVE", "XSAVE (and related) instructions are supported by hardware."} ,{CPUF_OSXSAVE, 0, "OSXSAVE", "XSAVE (and related) instructions are enabled."} ,{CPUF_AVX, 0, "AVX", "AVX instructions."} ,{CPUF_F16C, 0, "F16C", "half-precision convert instruction support."} ,{CPUF_RDRAND, 0, "RDRAND", "RDRAND instruction."} ,{CPUF_FPU, 0, "FPU", "Floating Point Unit On-Chip."} ,{CPUF_VME, 0, "VME", "Virtual 8086 Mode Enhancements."} ,{CPUF_DE, 0, "DE", "Debugging Extensions."} ,{CPUF_PSE, 0, "PSE", "Page Size Extension."} ,{CPUF_TSC, 0, "TSC", "Time Stamp Counter."} ,{CPUF_MSR, 0, "MSR", "Model Specific Registers RDMSR and WRMSR Instructions."} ,{CPUF_PAE, 0, "PAE", "Physical Address Extension."} ,{CPUF_MCE, 0, "MCE", "Machine Check Exception."} ,{CPUF_CX8, 0, "CX8", "CMPXCHG8B instruction."} ,{CPUF_APIC, 0, "APIC", "APIC(Advanced Programmable Interrupt Controller) On-Chip."} ,{CPUF_SEP, 0, "SEP", "Fast System Call instructions, SYSENTER and SYSEXIT."} ,{CPUF_MTRR, 0, "MTRR", "Memory Type Range Registers."} ,{CPUF_PGE, 0, "PGE", "Page Global Enable."} ,{CPUF_MCA, 0, "MCA", "Machine-Check Architecture."} ,{CPUF_CMOV, 0, "CMOV", "Conditional Move Instructions."} ,{CPUF_PAT, 0, "PAT", "Page Attribute Table."} ,{CPUF_PSE36, 0, "PSE36", "36-Bit Page Size Extension."} ,{CPUF_PSN, 0, "PSN", "Processor Serial Number."} ,{CPUF_CLFSH, 0, "CLFSH", "CLFLUSH Instruction."} ,{CPUF_DS, 0, "DS", "Debug Store."} ,{CPUF_ACPI, 0, "ACPI", "Thermal Monitor and Software Controlled Clock Facilities."} ,{CPUF_MMX, 0, "MMX", "MMX instructions."} ,{CPUF_FXSR, 0, "FXSR", "FXSAVE and FXRSTOR instructions."} ,{CPUF_SSE, 0, "SSE", "Streaming SIMD Extensions."} ,{CPUF_SSE2, 0, "SSE2", "Streaming SIMD Extensions 2."} ,{CPUF_SS, 0, "SS", "Self Snoop."} ,{CPUF_HTT, 0, "HTT", "Max APIC IDs reserved field is Valid."} ,{CPUF_TM, 0, "TM", "Thermal Monitor."} ,{CPUF_PBE, 0, "PBE", "Pending Break Enable."} ,{CPUF_Cache_Type, 0, "Cache_Type", "Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified)."} ,{CPUF_Cache_Level, 0, "Cache_Level", "Cache Level (Starts at 1)."} ,{CPUF_CACHE_SI, 0, "CACHE_SI", "Self Initializing cache level."} ,{CPUF_CACHE_FA, 0, "CACHE_FA", "Fully Associative cache."} ,{CPUF_MaxApicIdShare, 0, "MaxApicIdShare", "Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding)."} ,{CPUF_MaxApicIdCore, 0, "MaxApicIdCore", "Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding)."} ,{CPUF_Cache_LineSize, 0, "Cache_LineSize", "System Coherency Line Size (plus 1 encoding)."} ,{CPUF_Cache_Partitions, 0, "Cache_Partitions", "Physical Line partitions (plus 1 encoding)."} ,{CPUF_Cache_Ways, 0, "Cache_Ways", "Ways of Associativity (plus 1 encoding)."} ,{CPUF_Cache_Sets, 0, "Cache_Sets", "Number of Sets (plus 1 encoding)."} ,{CPUF_CACHE_INVD, 0, "CACHE_INVD", "WBINVD/INVD behavior on lower level caches."} ,{CPUF_CACHE_INCLUSIVENESS, 0, "CACHE_INCLUSIVENESS", "Cache is inclusive of lower cache levels."} ,{CPUF_CACHE_COMPLEXINDEX, 0, "CACHE_COMPLEXINDEX", "Complex Cache Indexing."} ,{CPUF_MonLineSizeMin, 0, "MonLineSizeMin", "Smallest monitor line size in bytes."} ,{CPUF_MonLineSizeMax, 0, "MonLineSizeMax", "Largest monitor-line size in bytes."} ,{CPUF_EMX, 0, "EMX", "Enumerate MONITOR/MWAIT extensions."} ,{CPUF_IBE, 0, "IBE", "Interrupt Break-Event."} ,{CPUF_MWAIT_Number_C0, 0, "MWAIT_Number_C0", "Number of C0 sub C-states supported using MWAIT."} ,{CPUF_MWAIT_Number_C1, 0, "MWAIT_Number_C1", "Number of C1 sub C-states supported using MWAIT."} ,{CPUF_MWAIT_Number_C2, 0, "MWAIT_Number_C2", "Number of C2 sub C-states supported using MWAIT."} ,{CPUF_MWAIT_Number_C3, 0, "MWAIT_Number_C3", "Number of C3 sub C-states supported using MWAIT."} ,{CPUF_MWAIT_Number_C4, 0, "MWAIT_Number_C4", "Number of C4 sub C-states supported using MWAIT."} ,{CPUF_DTS, 0, "DTS", "Digital Thermal Sensor."} ,{CPUF_TURBO_BOOST, 0, "TURBO_BOOST", "Intel Turbo Boost Technology."} ,{CPUF_ARAT, 0, "ARAT", "Always Running APIC Timer."} ,{CPUF_PLN, 0, "PLN", "Power Limit Notification."} ,{CPUF_ECMD, 0, "ECMD", "Extended Clock Modulation Duty."} ,{CPUF_PTM, 0, "PTM", "Package Thermal Management."} ,{CPUF_DTS_ITs, 0, "DTS_ITs", "Number of Interrupt Thresholds in Digital Thermal Sensor."} ,{CPUF_PERF, 0, "PERF", "Hardware Coordination Feedback Capability."} ,{CPUF_ACNT2, 0, "ACNT2", "ACNT2 Capability."} ,{CPUF_ENERGY_PERF_BIAS, 0, "ENERGY_PERF_BIAS", "Performance-Energy Bias capability."} ,{CPUF_Max07Subleaf, 0, "Max07Subleaf", "Reports the maximum supported leaf 7 sub-leaf."} ,{CPUF_FSGSBASE, 0, "FSGSBASE", "Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE."} ,{CPUF_TSC_ADJUST, 0, "TSC_ADJUST", "IA32_TSC_ADJUST MSR is supported if 1."} ,{CPUF_BMI1, 0, "BMI1", "The first group of advanced bit manipulation extensions (ANDN, BEXTR, BLSI, BLSMK, BLSR, TZCNT)."} ,{CPUF_HLE, 0, "HLE", "Hardware Lock Elision."} ,{CPUF_AVX2, 0, "AVX2", "AVX2 instructions."} ,{CPUF_SMEP, 0, "SMEP", "Supervisor Mode Execution Protection."} ,{CPUF_BMI2, 0, "BMI2", "The second group of advanced bit manipulation extensions (BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)."} ,{CPUF_ERMS, 0, "ERMS", "Supports Enhanced REP MOVSB/STOSB."} ,{CPUF_INVPCID, 0, "INVPCID", "Invalidate Processor Context ID."} ,{CPUF_RTM, 0, "RTM", "Restricted Transactional Memory."} ,{CPUF_RDSEED, 0, "RDSEED", "RDSEED instruction."} ,{CPUF_ADX, 0, "ADX", "ADCX and ADOX instructions."} ,{CPUF_SMAP, 0, "SMAP", "Supervisor Mode Access Prevention."} ,{CPUF_PLATFORM_DCA_CAP, 0, "PLATFORM_DCA_CAP", "Value of PLATFORM_DCA_CAP MSR Bits [31:0] (Offset 1F8h)."} ,{CPUF_APM_Version, 0, "APM_Version", "Version ID of architectural performance monitoring."} ,{CPUF_APM_Counters, 0, "APM_Counters", "Number of general-purpose performance monitoring counters per logical processor."} ,{CPUF_APM_Bits, 0, "APM_Bits", "Bit width of general-purpose, performance monitoring counters."} ,{CPUF_APM_Length, 0, "APM_Length", "Length of EBX bit vector to enumerate architectural performance monitoring events."} ,{CPUF_APM_CC, 0, "APM_CC", "Core cycle event not available if 1."} ,{CPUF_APM_IR, 0, "APM_IR", "Instruction retired event not available if 1."} ,{CPUF_APM_RC, 0, "APM_RC", "Reference cycles event not available if 1."} ,{CPUF_APM_LLCR, 0, "APM_LLCR", "Last-level cache reference event not available if 1."} ,{CPUF_APM_LLCM, 0, "APM_LLCM", "Last-level cache misses event not available if 1."} ,{CPUF_APM_BIR, 0, "APM_BIR", "Branch instruction retired event not available if 1."} ,{CPUF_APM_BMR, 0, "APM_BMR", "Branch mispredict retired event not available if 1."} ,{CPUF_APM_FC_Number, 0, "APM_FC_Number", "Number of fixed-function performance counters."} ,{CPUF_APM_FC_Bits, 0, "APM_FC_Bits", "Bit width of fixed-function performance counters."} ,{CPUF_Topology_Bits, 0, "Topology_Bits", "Number of bits to shift right on x2APIC ID to get a unique topology ID of the next level type."} ,{CPUF_Topology_Number, 0, "Topology_Number", "Number of factory-configured logical processors at this level."} ,{CPUF_Topology_Level, 0, "Topology_Level", "Level number. Same value in ECX input."} ,{CPUF_Topology_Type, 0, "Topology_Type", "Level Type (0=Invalid, 1=Thread, 2=Core)."} ,{CPUF_X2APICID, 0, "X2APICID", "x2APIC ID."} ,{CPUF_XFeatureSupportedMaskLo, 0, "XFeatureSupportedMaskLo", "The lower 32 bits of XCR0(XFEATURE_ENABLED_MASK register)."} ,{CPUF_XFeatureEnabledSizeMax, 0, "XFeatureEnabledSizeMax", "Size in bytes of XSAVE/XRSTOR area for the currently enabled features in XCR0."} ,{CPUF_XFeatureSupportedSizeMax, 0, "XFeatureSupportedSizeMax", "Size in bytes of XSAVE/XRSTOR area for all features that the core supports."} ,{CPUF_XFeatureSupportedMaskHi, 0, "XFeatureSupportedMaskHi", "The upper 32 bits of XCR0(XFEATURE_ENABLED_MASK register)."} ,{CPUF_XSAVEOPT, 0, "XSAVEOPT", "XSAVEOPT is available."} ,{CPUF_YmmSaveStateSize, 0, "YmmSaveStateSize", "YMM save state byte size."} ,{CPUF_YmmSaveStateOffset, 0, "YmmSaveStateOffset", "YMM save state byte offset."} ,{CPUF_LwpSaveStateSize, 0, "LwpSaveStateSize", "LWP save state byte size."} ,{CPUF_LwpSaveStateOffset, 0, "LwpSaveStateOffset", "LWP save state byte offset."} ,{CPUF_LFuncExt, 0, "LFuncExt", "Largest extended function."} ,{CPUF_BrandId16, 0, "BrandId16", "16-bit Brand ID."} ,{CPUF_PkgType, 0, "PkgType", "Package type (Family[7:0] >= 10h)."} ,{CPUF_LahfSahf, 0, "LahfSahf", "LAHF and SAHF instruction support in 64-bit mode."} ,{CPUF_CmpLegacy, 0, "CmpLegacy", "core multi-processing legacy mode."} ,{CPUF_SVM, 0, "SVM", "secure virtual machine."} ,{CPUF_ExtApicSpace, 0, "ExtApicSpace", "extended APIC space."} ,{CPUF_AltMovCr8, 0, "AltMovCr8", "LOCK MOV CR0 means MOV CR8."} ,{CPUF_ABM, 0, "ABM", "advanced bit manipulation (LZCNT)."} ,{CPUF_SSE4A, 0, "SSE4A", "SSE4A instructions."} ,{CPUF_MisAlignSse, 0, "MisAlignSse", "misaligned SSE mode."} ,{CPUF_3DNowPrefetch, 0, "3DNowPrefetch", "PREFETCH and PREFETCHW instruction support."} ,{CPUF_OSVW, 0, "OSVW", "OS visible workaround."} ,{CPUF_IBS, 0, "IBS", "instruction based sampling."} ,{CPUF_XOP, 0, "XOP", "extended operation support."} ,{CPUF_SKINIT, 0, "SKINIT", "SKINIT and STGI are supported, independent of the value of MSRC000_0080[SVME]."} ,{CPUF_WDT, 0, "WDT", "watchdog timer support."} ,{CPUF_LWP, 0, "LWP", "lightweight profiling support."} ,{CPUF_FMA4, 0, "FMA4", "4-operand FMA instruction support."} ,{CPUF_BIT_NODEID, 0, "BIT_NODEID", "Indicates support for MSRC001_100C[NodeId, NodesPerProcessor]."} ,{CPUF_TBM, 0, "TBM", "Trailing bit manipulation instruction support."} ,{CPUF_TopologyExtensions, 0, "TopologyExtensions", "Topology extensions support."} ,{CPUF_SYSCALL, 0, "SYSCALL", "SYSCALL and SYSRET instructions."} ,{CPUF_XD, 0, "XD", "Execution Disable Bit."} ,{CPUF_MmxExt, 0, "MmxExt", "AMD extensions to MMX instructions."} ,{CPUF_FFXSR, 0, "FFXSR", "FXSAVE and FXRSTOR instruction optimizations."} ,{CPUF_Page1GB, 0, "Page1GB", "1-GB large page support."} ,{CPUF_RDTSCP, 0, "RDTSCP", "RDTSCP and TSC_AUX."} ,{CPUF_LM, 0, "LM", "64-bit long mode.(x86-64)"} ,{CPUF_3DNowExt, 0, "3DNowExt", "AMD extensions to 3DNow! instructions."} ,{CPUF_3DNow, 0, "3DNow", "3DNow! instructions."} ,{CPUF_L1ITlb2and4MSize, 0, "L1ITlb2and4MSize", "Instruction TLB number of entries for 2-MB and 4-MB pages."} ,{CPUF_L1ITlb2and4MAssoc, 0, "L1ITlb2and4MAssoc", "Instruction TLB associativity for 2-MB and 4-MB pages."} ,{CPUF_L1DTlb2and4MSize, 0, "L1DTlb2and4MSize", "Data TLB number of entries for 2-MB and 4-MB pages."} ,{CPUF_L1DTlb2and4MAssoc, 0, "L1DTlb2and4MAssoc", "Data TLB associativity for 2-MB and 4-MB pages."} ,{CPUF_L1ITlb4KSize, 0, "L1ITlb4KSize", "Instruction TLB number of entries for 4 KB pages."} ,{CPUF_L1ITlb4KAssoc, 0, "L1ITlb4KAssoc", "Instruction TLB associativity for 4KB pages."} ,{CPUF_L1DTlb4KSize, 0, "L1DTlb4KSize", "Data TLB number of entries for 4 KB pages."} ,{CPUF_L1DTlb4KAssoc, 0, "L1DTlb4KAssoc", "Data TLB associativity for 4 KB pages."} ,{CPUF_L1DcLineSize, 0, "L1DcLineSize", "L1 data cache line size in bytes."} ,{CPUF_L1DcLinesPerTag, 0, "L1DcLinesPerTag", "L1 data cache lines per tag."} ,{CPUF_L1DcAssoc, 0, "L1DcAssoc", "L1 data cache associativity."} ,{CPUF_L1DcSize, 0, "L1DcSize", "L1 data cache size in KB."} ,{CPUF_L1IcLineSize, 0, "L1IcLineSize", "L1 instruction cache line size in bytes"} ,{CPUF_L1IcLinesPerTag, 0, "L1IcLinesPerTag", "L1 instruction cache lines per tag."} ,{CPUF_L1IcAssoc, 0, "L1IcAssoc", "L1 instruction cache associativity."} ,{CPUF_L1IcSize, 0, "L1IcSize", "L1 instruction cache size KB."} ,{CPUF_L2ITlb2and4MSize, 0, "L2ITlb2and4MSize", "L2 instruction TLB number of entries for 2 MB and 4 MB pages."} ,{CPUF_L2ITlb2and4MAssoc, 0, "L2ITlb2and4MAssoc", "L2 instruction TLB associativity for 2 MB and 4 MB pages."} ,{CPUF_L2DTlb2and4MSize, 0, "L2DTlb2and4MSize", "L2 data TLB number of entries for 2 MB and 4 MB pages."} ,{CPUF_L2DTlb2and4MAssoc, 0, "L2DTlb2and4MAssoc", "L2 data TLB associativity for 2 MB and 4 MB pages."} ,{CPUF_L2ITlb4KSize, 0, "L2ITlb4KSize", "L2 instruction TLB number of entries for 4 KB pages."} ,{CPUF_L2ITlb4KAssoc, 0, "L2ITlb4KAssoc", "L2 instruction TLB associativity for 4 KB pages."} ,{CPUF_L2DTlb4KSize, 0, "L2DTlb4KSize", "L2 data TLB number of entries for 4 KB pages."} ,{CPUF_L2DTlb4KAssoc, 0, "L2DTlb4KAssoc", "L2 data TLB associativity for 4 KB pages."} ,{CPUF_L2LineSize, 0, "L2LineSize", "L2 cache line size in bytes."} ,{CPUF_L2LinesPerTag, 0, "L2LinesPerTag", "L2 cache lines per tag."} ,{CPUF_L2Assoc, 0, "L2Assoc", "L2 cache associativity."} ,{CPUF_L2Size, 0, "L2Size", "L2 cache size in KB."} ,{CPUF_L3LineSize, 0, "L3LineSize", "L3 cache line size in bytes."} ,{CPUF_L3LinesPerTag, 0, "L3LinesPerTag", "L3 cache lines per tag."} ,{CPUF_L3Assoc, 0, "L3Assoc", "L3 cache associativity."} ,{CPUF_L3Size, 0, "L3Size", "L3 cache size."} ,{CPUF_TS, 0, "TS", "Temperature sensor."} ,{CPUF_FID, 0, "FID", "Frequency ID control."} ,{CPUF_VID, 0, "VID", "Voltage ID control."} ,{CPUF_TTP, 0, "TTP", "THERMTRIP."} ,{CPUF_HTC, 0, "HTC", "TM: Hardware thermal control (HTC)."} ,{CPUF_100MHzSteps, 0, "100MHzSteps", "100 MHz multiplier Control."} ,{CPUF_HwPstate, 0, "HwPstate", "Hardware P-state control."} ,{CPUF_TscInvariant, 0, "TscInvariant", "TSC invariant."} ,{CPUF_CPB, 0, "CPB", "Core performance boost."} ,{CPUF_EffFreqRO, 0, "EffFreqRO", "Read-only effective frequency interface."} ,{CPUF_PhysAddrSize, 0, "PhysAddrSize", "Maximum physical byte address size in bits."} ,{CPUF_LinAddrSize, 0, "LinAddrSize", "Maximum linear byte address size in bits."} ,{CPUF_GuestPhysAddrSize, 0, "GuestPhysAddrSize", "Maximum guest physical byte address size in bits."} ,{CPUF_NC, 0, "NC", "number of physical cores - 1."} ,{CPUF_ApicIdCoreIdSize, 0, "ApicIdCoreIdSize", "APIC ID size. The number of bits in the initial APIC20[ApicId] value that indicate core ID within a processor."} ,{CPUF_SvmRev, 0, "SvmRev", "SVM revision."} ,{CPUF_NASID, 0, "NASID", "number of address space identifiers (ASID)."} ,{CPUF_NP, 0, "NP", "Nested paging."} ,{CPUF_LbrVirt, 0, "LbrVirt", "LBR virtualization."} ,{CPUF_SVML, 0, "SVML", "SVM lock. Indicates support for SVM-Lock."} ,{CPUF_NRIPS, 0, "NRIPS", "NRIP save. Indicates support for NRIP save on #VMEXIT."} ,{CPUF_TscRateMsr, 0, "TscRateMsr", "MSR based TSC rate control."} ,{CPUF_VmcbClean, 0, "VmcbClean", "VMCB clean bits. Indicates support for VMCB clean bits."} ,{CPUF_FlushByAsid, 0, "FlushByAsid", "Flush by ASID."} ,{CPUF_DecodeAssists, 0, "DecodeAssists", "Decode assists."} ,{CPUF_PauseFilter, 0, "PauseFilter", "Pause intercept filter."} ,{CPUF_PauseFilterThreshold, 0, "PauseFilterThreshold", "PAUSE filter threshold."} ,{CPUF_L1ITlb1GSize, 0, "L1ITlb1GSize", "L1 instruction TLB number of entries for 1 GB pages."} ,{CPUF_L1ITlb1GAssoc, 0, "L1ITlb1GAssoc", "L1 instruction TLB associativity for 1 GB pages."} ,{CPUF_L1DTlb1GSize, 0, "L1DTlb1GSize", "L1 data TLB number of entries for 1 GB pages."} ,{CPUF_L1DTlb1GAssoc, 0, "L1DTlb1GAssoc", "L1 data TLB associativity for 1 GB pages."} ,{CPUF_L2ITlb1GSize, 0, "L2ITlb1GSize", "L2 instruction TLB number of entries for 1 GB pages."} ,{CPUF_L2ITlb1GAssoc, 0, "L2ITlb1GAssoc", "L2 instruction TLB associativity for 1 GB pages."} ,{CPUF_L2DTlb1GSize, 0, "L2DTlb1GSize", "L2 data TLB number of entries for 1 GB pages."} ,{CPUF_L2DTlb1GAssoc, 0, "L2DTlb1GAssoc", "L2 data TLB associativity for 1 GB pages."} ,{CPUF_FP128, 0, "FP128", "128-bit SSE (multimedia) instructions are executed with full-width internal operations and pipelines rather than decomposing them into internal 64-bit suboperations."} ,{CPUF_MOVU, 0, "MOVU", "MOVU SSE (multimedia) instructions are more efficient and should be preferred to SSE(multimedia) MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS."} ,{CPUF_IBSFFV, 0, "IBSFFV", "IBS feature flags valid."} ,{CPUF_FetchSam, 0, "FetchSam", "IBS fetch sampling supported."} ,{CPUF_OpSam, 0, "OpSam", "IBS execution sampling supported."} ,{CPUF_RdWrOpCnt, 0, "RdWrOpCnt", "Read write of op counter supported."} ,{CPUF_OpCnt, 0, "OpCnt", "Op counting mode supported."} ,{CPUF_BrnTrgt, 0, "BrnTrgt", "Branch target address reporting supported."} ,{CPUF_OpCntExt, 0, "OpCntExt", "IbsOpCurCnt and IbsOpMaxCnt extend by 7 bits."} ,{CPUF_RipInvalidChk, 0, "RipInvalidChk", "Invalid RIP indication supported."} ,{CPUF_LwpAvail, 0, "LwpAvail", "LWP available."} ,{CPUF_LwpVAL, 0, "LwpVAL", "LWPVAL instruction available."} ,{CPUF_LwpIRE, 0, "LwpIRE", "instructions retired event available."} ,{CPUF_LwpBRE, 0, "LwpBRE", "branch retired event available."} ,{CPUF_LwpDME, 0, "LwpDME", "DC miss event available."} ,{CPUF_LwpCNH, 0, "LwpCNH", "core clocks not halted event available."} ,{CPUF_LwpRNH, 0, "LwpRNH", "core reference clocks not halted event available."} ,{CPUF_LwpInt, 0, "LwpInt", "interrupt on threshold overflow available."} ,{CPUF_LwpCbSize, 0, "LwpCbSize", "control block size. Size in bytes of the LWPCB."} ,{CPUF_LwpEventSize, 0, "LwpEventSize", "event record size. Size in bytes of an event record in the LWP event ring buffer."} ,{CPUF_LwpMaxEvents, 0, "LwpMaxEvents", "maximum EventId. Maximum EventId value that is supported."} ,{CPUF_LwpEventOffset, 0, "LwpEventOffset", "offset to the EventInterval1 field. Offset from the start of the LWPCB to the EventInterval1 field."} ,{CPUF_LwpLatencyMax, 0, "LwpLatencyMax", "latency counter bit size. Size in bits of the cache latency counters."} ,{CPUF_LwpDataAddress, 0, "LwpDataAddress", "data cache miss address valid."} ,{CPUF_LwpLatencyRnd, 0, "LwpLatencyRnd", "amount cache latency is rounded."} ,{CPUF_LwpVersion, 0, "LwpVersion", "version. Version of LWP implementation."} ,{CPUF_LwpMinBufferSize, 0, "LwpMinBufferSize", "event ring buffer size. Minimum size of the LWP event ring buffer, in units of 32 event records."} ,{CPUF_LwpBranchPrediction, 0, "LwpBranchPrediction", "branch prediction filtering supported."} ,{CPUF_LwpIpFiltering, 0, "LwpIpFiltering", "IP filtering supported."} ,{CPUF_LwpCacheLevels, 0, "LwpCacheLevels", "cache level filtering supported."} ,{CPUF_LwpCacheLatency, 0, "LwpCacheLatency", "cache latency filtering supported."} ,{CPUF_D_LwpAvail, 0, "D_LwpAvail", "lightweight profiling supported."} ,{CPUF_D_LwpVAL, 0, "D_LwpVAL", "LWPVAL instruction supported."} ,{CPUF_D_LwpIRE, 0, "D_LwpIRE", "instructions retired event supported."} ,{CPUF_D_LwpBRE, 0, "D_LwpBRE", "branch retired event supported."} ,{CPUF_D_LwpDME, 0, "D_LwpDME", "DC miss event supported."} ,{CPUF_D_LwpCNH, 0, "D_LwpCNH", "core clocks not halted event supported."} ,{CPUF_D_LwpRNH, 0, "D_LwpRNH", "core reference clocks not halted event supported."} ,{CPUF_D_LwpInt, 0, "D_LwpInt", "interrupt on threshold overflow supported."} ,{CPUF_CacheType, 0, "CacheType", "Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified)."} ,{CPUF_CacheLevel, 0, "CacheLevel", "Cache Level (Starts at 1)."} ,{CPUF_SelfInitialization, 0, "SelfInitialization", "Self Initializing cache level."} ,{CPUF_FullyAssociative, 0, "FullyAssociative", "Fully Associative cache."} ,{CPUF_NumSharingCache, 0, "NumSharingCache", "Number of cores sharing cache. The number of cores sharing this cache is NumSharingCache+1."} ,{CPUF_CacheLineSize, 0, "CacheLineSize", "Cache line size in bytes (plus 1 encoding)."} ,{CPUF_CachePhysPartitions, 0, "CachePhysPartitions", "Cache physical line partitions (plus 1 encoding)."} ,{CPUF_CacheNumWays, 0, "CacheNumWays", "Cache number of ways (plus 1 encoding)."} ,{CPUF_CacheNumSets, 0, "CacheNumSets", "Cache number of sets (plus 1 encoding)."} ,{CPUF_WBINVD, 0, "WBINVD", "Write-Back Invalidate/Invalidate (WBINVD/INVD)."} ,{CPUF_CacheInclusive, 0, "CacheInclusive", "Cache inclusive."} ,{CPUF_ExtendedApicId, 0, "ExtendedApicId", "extended APIC ID."} ,{CPUF_ComputeUnitId, 0, "ComputeUnitId", "compute unit ID. Identifies the processor compute unit ID."} ,{CPUF_CoresPerComputeUnit, 0, "CoresPerComputeUnit", "cores per compute unit. The number of cores per compute unit is CoresPerComputeUnit+1."} ,{CPUF_NodeId, 0, "NodeId", "Specifies the node ID."} ,{CPUF_NodesPerProcessor, 0, "NodesPerProcessor", "Specifies the number of nodes per processor."} }; const char* CCPUID::CacheDesc[] = { "Null descriptor, this byte contains no information" ,"Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries" ,"Instruction TLB: 4 MByte pages, fully associative, 2 entries" ,"Data TLB: 4 KByte pages, 4-way set associative, 64 entries" ,"Data TLB: 4 MByte pages, 4-way set associative, 8 entries" ,"Data TLB1: 4 MByte pages, 4-way set associative, 32 entries" ,"1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size" ,"" ,"1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size" ,"1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size" ,"1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size" ,"Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries" ,"1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size" ,"1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size" ,"1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size" ,"3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector" ,"3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" ,"" ,"3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" ,"" ,"" ,"" ,"3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" ,"" ,"" ,"1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size" ,"" ,"" ,"" ,"1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" ,"2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size" ,"2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size" ,"2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size" ,"2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size" ,"2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size" ,"3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size" ,"3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size" ,"2nd-level cache: 3MByte, 12-way set associative, 64 byte line size" ,"3rd-level cache: 4MB, 16-way set associative, 64-byte line size (Intel Xeon processor MP, Family 0FH, Model 06H); 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size" ,"3rd-level cache: 6MByte, 12-way set associative, 64 byte line size" ,"3rd-level cache: 8MByte, 16-way set associative, 64 byte line size" ,"3rd-level cache: 12MByte, 12-way set associative, 64 byte line size" ,"3rd-level cache: 16MByte, 16-way set associative, 64 byte line size" ,"2nd-level cache: 6MByte, 24-way set associative, 64 byte line size" ,"Instruction TLB: 4 KByte pages, 32 entries" ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries" ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries" ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries" ,"" ,"" ,"Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries" ,"Data TLB0: 4 MByte pages, 4-way set associative, 16 entries" ,"Data TLB0: 4 KByte pages, 4-way associative, 16 entries" ,"Data TLB0: 4 KByte pages, fully associative, 16 entries" ,"Data TLB0: 2-MByte or 4 MByte pages, 4-way set associative, 32 entries" ,"Data TLB: 4 KByte and 4 MByte pages, 64 entries" ,"Data TLB: 4 KByte and 4 MByte pages,128 entries" ,"Data TLB: 4 KByte and 4 MByte pages,256 entries" ,"" ,"" ,"" ,"1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size" ,"1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size" ,"1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"Trace cache: 12 K-μop, 8-way set associative" ,"Trace cache: 16 K-μop, 8-way set associative" ,"Trace cache: 32 K-μop, 8-way set associative" ,"" ,"" ,"" ,"Instruction TLB: 2M/4M pages, fully associative, 8 entries" ,"" ,"2nd-level cache: 1 MByte, 4-way set associative, 64byte line size" ,"2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" ,"2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" ,"2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" ,"2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector" ,"2nd-level cache: 2 MByte, 8-way set associative, 64byte line size" ,"" ,"2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size" ,"2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size" ,"" ,"2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size" ,"2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size" ,"2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size" ,"2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size" ,"2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size" ,"2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries" ,"Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries" ,"Instruction TLB: 4KByte pages, 4-way set associative, 64 entries" ,"Data TLB: 4 KByte pages, 4-way set associative, 128 entries" ,"Data TLB1: 4 KByte pages, 4-way associative, 256 entries" ,"" ,"" ,"" ,"" ,"" ,"Data TLB1: 4 KByte pages, 4-way associative, 64 entries" ,"" ,"" ,"" ,"" ,"" ,"Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries" ,"" ,"" ,"" ,"" ,"" ,"3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size" ,"3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size" ,"3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size" ,"" ,"" ,"" ,"3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size" ,"3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size" ,"3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size" ,"" ,"" ,"" ,"3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size" ,"3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size" ,"3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size" ,"" ,"" ,"" ,"3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size" ,"3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size" ,"3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size" ,"" ,"" ,"" ,"" ,"" ,"3rd-level cache: 12MByte, 24-way set associative, 64 byte line size" ,"3rd-level cache: 18MByte, 24-way set associative, 64 byte line size" ,"3rd-level cache: 24MByte, 24-way set associative, 64 byte line size" ,"" ,"" ,"" ,"64-Byte prefetching" ,"128-Byte prefetching" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters" }; const char* CCPUID::SseNames[] = { "None", "SSE", "SSE2", "SSE3", "SSSE3", "SSE4.1", "SSE4.2", }; const char* CCPUID::AvxNames[] = { "None", "AVX", "AVX2" }; //////////////////////////////////////////////////////////// // CCPUID //////////////////////////////////////////////////////////// // 构造函数. CCPUID::CCPUID() :_InfoCount(0), _LFuncStd(0), _LFuncExt(0), _BrandTrim(0) { _Vendor[0] = '\0'; _Brand[0] = '\0'; } // 刷新信息.在Info数组中追加一项. void CCPUID::RefreshInfo_Put(uint32_t fid, uint32_t fidsub, uint32_t CPUInfo[4]) { if (_InfoCount>=MAX_CPUIDINFO) return; Info[_InfoCount].fid = fid; Info[_InfoCount].fidsub = fidsub; Info[_InfoCount].dw[0] = CPUInfo[0]; Info[_InfoCount].dw[1] = CPUInfo[1]; Info[_InfoCount].dw[2] = CPUInfo[2]; Info[_InfoCount].dw[3] = CPUInfo[3]; ++_InfoCount; } // 刷新信息. void CCPUID::RefreshInfo() { uint32_t CPUInfo[4]; uint32_t nmax; uint32_t i,j; // == 将CPUID信息保存到Info数组 == _InfoCount = 0; // 标准功能. getcpuid(CPUInfo, 0); RefreshInfo_Put(0, 0, CPUInfo); nmax = CPUInfo[0]; // CPUID(0).EAX[31:0]=LFuncStd _LFuncStd = nmax; for(i=1; i<=nmax; ++i) { getcpuidex(CPUInfo, i, 0); RefreshInfo_Put(i, 0, CPUInfo); // fidsub if (0x4==i) // Deterministic Cache Parameters (Function 04h) { j=1; while(true) { getcpuidex(CPUInfo, i, j); if (0==(CPUInfo[0]&0x1F)) break; // EAX[4:0]=Cache_Type RefreshInfo_Put(i, j, CPUInfo); // next ++j; } } else if (0xB==i) // x2APIC Features / Processor Topology (Function 0Bh) { j=1; while(true) { getcpuidex(CPUInfo, i, j); if (0==CPUInfo[0] && 0==CPUInfo[1]) break; // until EAX=0 and EBX=0 RefreshInfo_Put(i, j, CPUInfo); // next ++j; } } else if (0xD==i) // XSAVE Features (Function 0Dh) { // fidsub = 1 j=1; getcpuidex(CPUInfo, i, j); RefreshInfo_Put(i, j, CPUInfo); // fidsub >= 2 for(j=2; j<=63; ++j) { getcpuidex(CPUInfo, i, j); if (0!=CPUInfo[0] || 0!=CPUInfo[1] || 0!=CPUInfo[2] || 0!=CPUInfo[3]) { RefreshInfo_Put(i, j, CPUInfo); } } } } // 扩展功能. getcpuid(CPUInfo, 0x80000000U); RefreshInfo_Put(0x80000000U, 0, CPUInfo); nmax = CPUInfo[0]; // CPUID(0x80000000).EAX[31:0]=LFuncExt _LFuncExt = nmax; if (nmax!=0) { for(i=0x80000001U; i<=nmax; ++i) { getcpuidex(CPUInfo, i, 0); RefreshInfo_Put(i, 0, CPUInfo); // fidsub if (0x8000001DU==i) // Cache Properties (Function 8000001Dh) { j=1; while(true) { getcpuidex(CPUInfo, i, j); if (0==(CPUInfo[0]&0x1F)) break; // EAX[4:0]=Cache_Type RefreshInfo_Put(i, j, CPUInfo); // next ++j; } } } } } // 刷新属性. void CCPUID::RefreshProperty() { uint32_t dwBuf[4]; // Vendor GetData(dwBuf, 0); // Function 0: Vendor-ID and Largest Standard Function uint32_t* pVendor = (uint32_t *)_Vendor; // 避免GCC的 -Wstrict-aliasing 警告. pVendor[0] = dwBuf[1]; // ebx: 前四个字符. pVendor[1] = dwBuf[3]; // edx: 中间四个字符. pVendor[2] = dwBuf[2]; // ecx: 最后四个字符. _Vendor[12] = '\0'; // Brand _Brand[0] = '\0'; if (_LFuncExt >= 0x80000004) { // Function 80000002h,80000003h,80000004h: Processor Brand String GetData((uint32_t *)&_Brand[0], 0x80000002); // 前16个字符. GetData((uint32_t *)&_Brand[16], 0x80000003); // 中间16个字符. GetData((uint32_t *)&_Brand[32], 0x80000004); // 最后16个字符. _Brand[48] = '\0'; } _BrandTrim = &_Brand[0]; while('\0'!=*_BrandTrim && ' '==*_BrandTrim) ++_BrandTrim; // 去除首都空格. // SIMD _mmx = simd_mmx(&_hwmmx); _sse = simd_sse_level(&_hwsse); _avx = simd_avx_level(&_hwavx); } // 刷新所有. void CCPUID::RefreshAll() { RefreshInfo(); RefreshProperty(); } // 取得信息. // // return: 成功时返回LPCPUIDINFO. 如果失败, 便返回NULL. // InfoType: 功能号. 即CPUID指令的eax参数. // ECXValue: 子功能号. 即CPUID指令的ecx参数. LPCCPUIDINFO CCPUID::GetInfo(uint32_t InfoType, uint32_t ECXValue) const { // 顺序搜索. for(int i=0; i<InfoCount(); ++i) { const CPUIDINFO& v = Info[i]; if (InfoType==v.fid && ECXValue==v.fidsub) { return &v; } } return NULL; } // 取得数据. // // CPUInfo: 成功时返回4个DWORD. 如果失败, 便返回全0. // InfoType: 功能号. 即CPUID指令的eax参数. // ECXValue: 子功能号. 即CPUID指令的ecx参数. void CCPUID::GetData(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue) const { LPCCPUIDINFO p = GetInfo(InfoType, ECXValue); if (NULL==p) { CPUInfo[0] = 0; CPUInfo[1] = 0; CPUInfo[2] = 0; CPUInfo[3] = 0; return; } CPUInfo[0] = p->dw[0]; CPUInfo[1] = p->dw[1]; CPUInfo[2] = p->dw[2]; CPUInfo[3] = p->dw[3]; } // 取得CPUID字段 uint32_t CCPUID::GetField(CPUIDFIELD cpuf) const { LPCCPUIDINFO p = GetInfo(CPUIDFIELD_FID(cpuf), CPUIDFIELD_FIDSUB(cpuf)); if (NULL==p) return 0; return getcpuidfield_buf(p->dw, cpuf); } int CCPUID::simd_mmx(int* phwmmx) const { int rt = 0; // result #ifdef CCPUID_X86 const uint32_t BIT_D_MMX = 0x00800000; // bit 23 uint32_t dwBuf[4]; // check processor support GetData(dwBuf, 1); // Function 1: Feature Information if ( dwBuf[3] & BIT_D_MMX ) rt=1; if (NULL!=phwmmx) *phwmmx=rt; // check OS support if ( rt ) { #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) // VC编译器不支持64位下的MMX. rt=0; #else try { _mm_empty(); // MMX instruction: emms } catch(...) { rt=0; } #endif // #if defined(_M_X64) && defined(_MSC_VER) } #else // #ifdef CCPUID_X86 if (NULL!=phwmmx) *phwmmx=rt; #endif // #ifdef CCPUID_X86 return rt; } int CCPUID::simd_sse_level(int* phwsse) const { int rt = SIMD_SSE_NONE; // result #ifdef CCPUID_X86 const uint32_t BIT_D_SSE = 0x02000000; // bit 25 const uint32_t BIT_D_SSE2 = 0x04000000; // bit 26 const uint32_t BIT_C_SSE3 = 0x00000001; // bit 0 const uint32_t BIT_C_SSSE3 = 0x00000100; // bit 9 const uint32_t BIT_C_SSE41 = 0x00080000; // bit 19 const uint32_t BIT_C_SSE42 = 0x00100000; // bit 20 uint32_t dwBuf[4]; // check processor support GetData(dwBuf, 1); // Function 1: Feature Information if ( dwBuf[3] & BIT_D_SSE ) { rt = SIMD_SSE_1; if ( dwBuf[3] & BIT_D_SSE2 ) { rt = SIMD_SSE_2; if ( dwBuf[2] & BIT_C_SSE3 ) { rt = SIMD_SSE_3; if ( dwBuf[2] & BIT_C_SSSE3 ) { rt = SIMD_SSE_3S; if ( dwBuf[2] & BIT_C_SSE41 ) { rt = SIMD_SSE_41; if ( dwBuf[2] & BIT_C_SSE42 ) { rt = SIMD_SSE_42; } } } } } } if (NULL!=phwsse) *phwsse=rt; // check OS support try { __m128 xmm1 = _mm_setzero_ps(); // SSE instruction: xorps int* pxmm1 = (int*)&xmm1; // 避免GCC的 -Wstrict-aliasing 警告. if (0!=*pxmm1) rt = SIMD_SSE_NONE; // 避免Release模式编译优化时剔除_mm_setzero_ps. } catch(...) { rt = SIMD_SSE_NONE; } #else // #ifdef CCPUID_X86 if (NULL!=phwsse) *phwsse=rt; #endif // #ifdef CCPUID_X86 return rt; } int CCPUID::simd_avx_level(int* phwavx) const { int rt = SIMD_AVX_NONE; // result #ifdef CCPUID_X86 // check processor support if (0!=GetField(CPUF_AVX)) { rt = SIMD_AVX_1; if (0!=GetField(CPUF_AVX2)) { rt = SIMD_AVX_2; } } if (NULL!=phwavx) *phwavx=rt; // check OS support if (0!=GetField(CPUF_OSXSAVE)) // XGETBV enabled for application use. { uint32_t n = GetField(CPUF_XFeatureSupportedMaskLo); // XCR0: XFeatureSupportedMask register. if (6!=(n&6)) // XCR0[2:1] = ‘11b’ (XMM state and YMM state are enabled by OS). { rt = SIMD_AVX_NONE; } } #else // #ifdef CCPUID_X86 if (NULL!=phwavx) *phwavx=rt; #endif // #ifdef CCPUID_X86 return rt; }
2.5 testccpuid.cpp : [C++] 测试ccpuid.hpp, 显示所有的CPUID信息
全部代码——
#include <stdio.h> #include "ccpuid.hpp" bool bShowDesc = true; // 显示描述信息 // 获取程序位数(被编译为多少位的代码) int GetProgramBits() { return sizeof(int*) * 8; } // 打印CPUID字段_某项. void prtCcpuid_Item(uint32_t fid, uint32_t fidsub, const uint32_t CPUInfo[4]) { static const char* RegName[4] = { "EAX", "EBX", "ECX", "EDX" }; uint32_t mask = CPUIDFIELD_MASK_FID | CPUIDFIELD_MASK_FIDSUB; uint32_t cur = CPUIDFIELD_MAKE(fid, fidsub, 0, 0, 1) & mask; int i; for(i=0; i<CCPUID::CPUFDescLen; ++i) { const CPUIDFIELDDESC& v = CCPUID::CPUFDesc[i]; if ((v.cpuf&mask)==cur) { CPUIDFIELD f = v.cpuf; uint32_t bits = CPUIDFIELD_LEN(f); uint32_t pos = CPUIDFIELD_POS(f); uint32_t reg = CPUIDFIELD_REG(f); uint32_t 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<ccid.InfoCount(); ++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的字段来解析各个子功能号的信息。 uint32_t 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) { uint32_t 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; } } } } } } int main(int argc, char* argv[]) { int i; //CCPUID ccid; //ccid.RefreshAll(); CCPUID& ccid = CCPUID::cur(); printf("testccpuid v1.02 (%dbit)\n\n", GetProgramBits()); // base info 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()); // simd info 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<(int)(sizeof(CCPUID::SseNames)/sizeof(CCPUID::SseNames[0])); ++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<(int)(sizeof(CCPUID::AvxNames)/sizeof(CCPUID::AvxNames[0])); ++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)); // field info printf("== fields ==\n"); prtCcpuid(ccid); return 0; }
2.6 makefile
makefile——
# flags CC = g++ CFLAGS = -Wall -msse LFLAGS = # args RELEASE =0 BITS = # [args] 生成模式. 0代表debug模式, 1代表release模式. make RELEASE=1. ifeq ($(RELEASE),0) # debug CFLAGS += -g else # release CFLAGS += -static -O3 -DNDEBUG LFLAGS += -static endif # [args] 程序位数. 32代表32位程序, 64代表64位程序, 其他默认. make BITS=32. ifeq ($(BITS),32) CFLAGS += -m32 LFLAGS += -m32 else ifeq ($(BITS),64) CFLAGS += -m64 LFLAGS += -m64 else endif endif .PHONY : all clean # files TARGETS = testccpuid testccpuidc OBJS = testccpuid.o ccpuid.o all : $(TARGETS) testccpuid : $(OBJS) $(CC) $(LFLAGS) -o $@ $^ ccpuid.o : ccpuid.cpp ccpuid.hpp ccpuid.h $(CC) $(CFLAGS) -c $< testccpuid.o : testccpuid.cpp ccpuid.hpp ccpuid.h $(CC) $(CFLAGS) -c $< testccpuidc : testccpuidc.c ccpuid.h gcc $(CFLAGS) -o $@ $< clean : rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))
三、测试结果
在以下编译器中成功编译——
VC6:x86版。
VC2003:x86版。
VC2005:x86版。
VC2010:x86版、x64版。
GCC 4.7.0(Fedora 17 x64):x86版、x64版。
GCC 4.6.2(MinGW (20120426)):x86版。
GCC 4.6.1(TDM-GCC (MinGW-w64)):x86版、x64版。
llvm-gcc-4.2(Mac OS X Lion 10.7.4, Xcode 4.4.1):x86版、x64版。
在虚拟机中Mac OS X Lion 10.7.4系统上运行testccpuid,它对Intel i3-2310M的检测结果为——
testccpuid v1.02 (64bit) CCPUID.Vendor: GenuineIntel CCPUID.BrandTrim: Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz CCPUID.InfoCount: 17 CCPUID.LFuncStd: 00000005h CCPUID.LFuncExt: 80000008h CCPUID.MMX: 1 // hw: 1 CCPUID.SSE: 3 // hw: 3 SSE SSE2 SSE3 SSE4A: 0 AES: 0 PCLMULQDQ: 0 CCPUID.AVX: 0 // hw: 0 F16C: 0 FMA: 0 FMA4: 0 XOP: 0 == fields == 0x00000000[0]: 00000005 756E6547 6C65746E 49656E69 EAX[31: 0]=LFuncStd: 0x5 (5) // largest standard function. Vendor: GenuineIntel 0x00000001[0]: 000206A7 01020800 00000201 178BFBFF EAX[ 3: 0]=Stepping: 0x7 (7) // processor stepping. EAX[ 7: 4]=BaseModel: 0xA (10) // base processor model. EAX[11: 8]=BaseFamily: 0x6 (6) // base processor family. EAX[13:12]=ProcessorType: 0x0 (0) // processor type. EAX[19:16]=ExtModel: 0x2 (2) // processor extended model. EAX[27:20]=ExtFamily: 0x0 (0) // processor extended family. EBX[ 7: 0]=BrandId8: 0x0 (0) // 8-bit brand ID. EBX[15: 8]=CLFlush: 0x8 (8) // CLFLUSH line size. (*8) EBX[23:16]=MaxApicId: 0x2 (2) // Maximum number of addressable IDs for logical processors in this physical package. EBX[31:24]=ApicId: 0x1 (1) // Initial local APIC physical ID(8-bit). ECX[ 0]=SSE3: 0x1 (1) // Streaming SIMD Extensions 3. ECX[ 1]=PCLMULQDQ: 0x0 (0) // PCLMULQDQ instruction. ECX[ 2]=DTES64: 0x0 (0) // 64-bit DS Area. ECX[ 3]=MONITOR: 0x0 (0) // MONITOR/MWAIT instructions. ECX[ 4]=DS_CPL: 0x0 (0) // CPL Qualified Debug Store. ECX[ 5]=VMX: 0x0 (0) // Virtual Machine Extensions. ECX[ 6]=SMX: 0x0 (0) // Safer Mode Extensions. ECX[ 7]=EIST: 0x0 (0) // Enhanced Intel SpeedStep technology. ECX[ 8]=TM2: 0x0 (0) // Thermal Monitor 2. ECX[ 9]=SSSE3: 0x1 (1) // Supplemental Streaming SIMD Extensions 3 (SSSE3). ECX[ 10]=CNXT_ID: 0x0 (0) // L1 Context ID. ECX[ 12]=FMA: 0x0 (0) // supports FMA extensions using YMM state. ECX[ 13]=CX16: 0x0 (0) // CMPXCHG16B instruction. ECX[ 14]=xTPR: 0x0 (0) // xTPR Update Control. Can disable sending Task Priority messages. ECX[ 15]=PDCM: 0x0 (0) // Perfmon and Debug Capability. ECX[ 17]=PCID: 0x0 (0) // Process Context Identifiers. ECX[ 18]=DCA: 0x0 (0) // Direct Cache Access. ECX[ 19]=SSE41: 0x0 (0) // SSE4.1 instructions. ECX[ 20]=SSE42: 0x0 (0) // SSE4.2 instructions. ECX[ 21]=x2APIC: 0x0 (0) // Extended xAPIC Support. ECX[ 22]=MOVBE: 0x0 (0) // MOVBE Instruction. ECX[ 23]=POPCNT: 0x0 (0) // POPCNT instruction. ECX[ 24]=TSC_DEADLINE: 0x0 (0) // Local APIC timer supports one-shot operation using a TSC deadline value. ECX[ 25]=AES: 0x0 (0) // Advanced Encryption Standard (AES) Instructions. ECX[ 26]=XSAVE: 0x0 (0) // XSAVE (and related) instructions are supported by hardware. ECX[ 27]=OSXSAVE: 0x0 (0) // XSAVE (and related) instructions are enabled. ECX[ 28]=AVX: 0x0 (0) // AVX instructions. ECX[ 29]=F16C: 0x0 (0) // half-precision convert instruction support. ECX[ 30]=RDRAND: 0x0 (0) // RDRAND instruction. EDX[ 0]=FPU: 0x1 (1) // Floating Point Unit On-Chip. EDX[ 1]=VME: 0x1 (1) // Virtual 8086 Mode Enhancements. EDX[ 2]=DE: 0x1 (1) // Debugging Extensions. EDX[ 3]=PSE: 0x1 (1) // Page Size Extension. EDX[ 4]=TSC: 0x1 (1) // Time Stamp Counter. EDX[ 5]=MSR: 0x1 (1) // Model Specific Registers RDMSR and WRMSR Instructions. EDX[ 6]=PAE: 0x1 (1) // Physical Address Extension. EDX[ 7]=MCE: 0x1 (1) // Machine Check Exception. EDX[ 8]=CX8: 0x1 (1) // CMPXCHG8B instruction. EDX[ 9]=APIC: 0x1 (1) // APIC(Advanced Programmable Interrupt Controller) On-Chip. EDX[ 11]=SEP: 0x1 (1) // Fast System Call instructions, SYSENTER and SYSEXIT. EDX[ 12]=MTRR: 0x1 (1) // Memory Type Range Registers. EDX[ 13]=PGE: 0x1 (1) // Page Global Enable. EDX[ 14]=MCA: 0x1 (1) // Machine-Check Architecture. EDX[ 15]=CMOV: 0x1 (1) // Conditional Move Instructions. EDX[ 16]=PAT: 0x1 (1) // Page Attribute Table. EDX[ 17]=PSE36: 0x1 (1) // 36-Bit Page Size Extension. EDX[ 18]=PSN: 0x0 (0) // Processor Serial Number. EDX[ 19]=CLFSH: 0x1 (1) // CLFLUSH Instruction. EDX[ 21]=DS: 0x0 (0) // Debug Store. EDX[ 22]=ACPI: 0x0 (0) // Thermal Monitor and Software Controlled Clock Facilities. EDX[ 23]=MMX: 0x1 (1) // MMX instructions. EDX[ 24]=FXSR: 0x1 (1) // FXSAVE and FXRSTOR instructions. EDX[ 25]=SSE: 0x1 (1) // Streaming SIMD Extensions. EDX[ 26]=SSE2: 0x1 (1) // Streaming SIMD Extensions 2. EDX[ 27]=SS: 0x0 (0) // Self Snoop. EDX[ 28]=HTT: 0x1 (1) // Max APIC IDs reserved field is Valid. EDX[ 29]=TM: 0x0 (0) // Thermal Monitor. EDX[ 31]=PBE: 0x0 (0) // Pending Break Enable. 0x00000002[0]: 76035A01 00F0B2FF 00000000 00CA0000 0x5A: Data TLB: 4 KByte and 4 MByte pages, 64 entries 0x03: Data TLB: 4 KByte pages, 4-way set associative, 64 entries 0x76: Instruction TLB: 2M/4M pages, fully associative, 8 entries 0xFF: CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters 0xB2: Instruction TLB: 4KByte pages, 4-way set associative, 64 entries 0xF0: 64-Byte prefetching 0xCA: Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries 0x00000003[0]: 00000000 00000000 00000000 00000000 0x00000004[0]: 04000021 01C0003F 0000003F 00000000 EAX[ 4: 0]=Cache_Type: 0x1 (1) // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified). EAX[ 7: 5]=Cache_Level: 0x1 (1) // Cache Level (Starts at 1). EAX[ 8]=CACHE_SI: 0x0 (0) // Self Initializing cache level. EAX[ 9]=CACHE_FA: 0x0 (0) // Fully Associative cache. EAX[25:14]=MaxApicIdShare: 0x0 (0) // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding). EAX[31:26]=MaxApicIdCore: 0x1 (1) // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding). EBX[11: 0]=Cache_LineSize: 0x3F (63) // System Coherency Line Size (plus 1 encoding). EBX[21:12]=Cache_Partitions: 0x0 (0) // Physical Line partitions (plus 1 encoding). EBX[31:22]=Cache_Ways: 0x7 (7) // Ways of Associativity (plus 1 encoding). ECX[31: 0]=Cache_Sets: 0x3F (63) // Number of Sets (plus 1 encoding). EDX[ 0]=CACHE_INVD: 0x0 (0) // WBINVD/INVD behavior on lower level caches. EDX[ 1]=CACHE_INCLUSIVENESS: 0x0 (0) // Cache is inclusive of lower cache levels. EDX[ 2]=CACHE_COMPLEXINDEX: 0x0 (0) // Complex Cache Indexing. 0x00000004[1]: 04000021 01C0003F 0000003F 00000000 EAX[ 4: 0]=Cache_Type: 0x1 (1) // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified). EAX[ 7: 5]=Cache_Level: 0x1 (1) // Cache Level (Starts at 1). EAX[ 8]=CACHE_SI: 0x0 (0) // Self Initializing cache level. EAX[ 9]=CACHE_FA: 0x0 (0) // Fully Associative cache. EAX[25:14]=MaxApicIdShare: 0x0 (0) // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding). EAX[31:26]=MaxApicIdCore: 0x1 (1) // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding). EBX[11: 0]=Cache_LineSize: 0x3F (63) // System Coherency Line Size (plus 1 encoding). EBX[21:12]=Cache_Partitions: 0x0 (0) // Physical Line partitions (plus 1 encoding). EBX[31:22]=Cache_Ways: 0x7 (7) // Ways of Associativity (plus 1 encoding). ECX[31: 0]=Cache_Sets: 0x3F (63) // Number of Sets (plus 1 encoding). EDX[ 0]=CACHE_INVD: 0x0 (0) // WBINVD/INVD behavior on lower level caches. EDX[ 1]=CACHE_INCLUSIVENESS: 0x0 (0) // Cache is inclusive of lower cache levels. EDX[ 2]=CACHE_COMPLEXINDEX: 0x0 (0) // Complex Cache Indexing. 0x00000004[2]: 04004041 05C0003F 00000FFF 00000000 EAX[ 4: 0]=Cache_Type: 0x1 (1) // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified). EAX[ 7: 5]=Cache_Level: 0x2 (2) // Cache Level (Starts at 1). EAX[ 8]=CACHE_SI: 0x0 (0) // Self Initializing cache level. EAX[ 9]=CACHE_FA: 0x0 (0) // Fully Associative cache. EAX[25:14]=MaxApicIdShare: 0x1 (1) // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding). EAX[31:26]=MaxApicIdCore: 0x1 (1) // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding). EBX[11: 0]=Cache_LineSize: 0x3F (63) // System Coherency Line Size (plus 1 encoding). EBX[21:12]=Cache_Partitions: 0x0 (0) // Physical Line partitions (plus 1 encoding). EBX[31:22]=Cache_Ways: 0x17 (23) // Ways of Associativity (plus 1 encoding). ECX[31: 0]=Cache_Sets: 0xFFF (4095) // Number of Sets (plus 1 encoding). EDX[ 0]=CACHE_INVD: 0x0 (0) // WBINVD/INVD behavior on lower level caches. EDX[ 1]=CACHE_INCLUSIVENESS: 0x0 (0) // Cache is inclusive of lower cache levels. EDX[ 2]=CACHE_COMPLEXINDEX: 0x0 (0) // Complex Cache Indexing. 0x00000005[0]: 00000000 00000000 00000003 00000000 EAX[15: 0]=MonLineSizeMin: 0x0 (0) // Smallest monitor line size in bytes. EBX[15: 0]=MonLineSizeMax: 0x0 (0) // Largest monitor-line size in bytes. ECX[ 0]=EMX: 0x1 (1) // Enumerate MONITOR/MWAIT extensions. ECX[ 1]=IBE: 0x1 (1) // Interrupt Break-Event. EDX[ 3: 0]=MWAIT_Number_C0: 0x0 (0) // Number of C0 sub C-states supported using MWAIT. EDX[ 7: 4]=MWAIT_Number_C1: 0x0 (0) // Number of C1 sub C-states supported using MWAIT. EDX[11: 8]=MWAIT_Number_C2: 0x0 (0) // Number of C2 sub C-states supported using MWAIT. EDX[15:12]=MWAIT_Number_C3: 0x0 (0) // Number of C3 sub C-states supported using MWAIT. EDX[19:16]=MWAIT_Number_C4: 0x0 (0) // Number of C4 sub C-states supported using MWAIT. 0x80000000[0]: 80000008 00000000 00000000 00000000 EAX[31: 0]=LFuncExt: 0x80000008 (2147483656) // Largest extended function. 0x80000001[0]: 00000000 00000000 00000001 20100800 EBX[15: 0]=BrandId16: 0x0 (0) // 16-bit Brand ID. EBX[31:28]=PkgType: 0x0 (0) // Package type (Family[7:0] >= 10h). ECX[ 0]=LahfSahf: 0x1 (1) // LAHF and SAHF instruction support in 64-bit mode. ECX[ 1]=CmpLegacy: 0x0 (0) // core multi-processing legacy mode. ECX[ 2]=SVM: 0x0 (0) // secure virtual machine. ECX[ 3]=ExtApicSpace: 0x0 (0) // extended APIC space. ECX[ 4]=AltMovCr8: 0x0 (0) // LOCK MOV CR0 means MOV CR8. ECX[ 5]=ABM: 0x0 (0) // advanced bit manipulation (LZCNT). ECX[ 6]=SSE4A: 0x0 (0) // SSE4A instructions. ECX[ 7]=MisAlignSse: 0x0 (0) // misaligned SSE mode. ECX[ 8]=3DNowPrefetch: 0x0 (0) // PREFETCH and PREFETCHW instruction support. ECX[ 9]=OSVW: 0x0 (0) // OS visible workaround. ECX[ 10]=IBS: 0x0 (0) // instruction based sampling. ECX[ 11]=XOP: 0x0 (0) // extended operation support. ECX[ 12]=SKINIT: 0x0 (0) // SKINIT and STGI are supported, independent of the value of MSRC000_0080[SVME]. ECX[ 13]=WDT: 0x0 (0) // watchdog timer support. ECX[ 15]=LWP: 0x0 (0) // lightweight profiling support. ECX[ 16]=FMA4: 0x0 (0) // 4-operand FMA instruction support. ECX[ 19]=BIT_NODEID: 0x0 (0) // Indicates support for MSRC001_100C[NodeId, NodesPerProcessor]. ECX[ 21]=TBM: 0x0 (0) // Trailing bit manipulation instruction support. ECX[ 22]=TopologyExtensions: 0x0 (0) // Topology extensions support. EDX[ 11]=SYSCALL: 0x1 (1) // SYSCALL and SYSRET instructions. EDX[ 20]=XD: 0x1 (1) // Execution Disable Bit. EDX[ 22]=MmxExt: 0x0 (0) // AMD extensions to MMX instructions. EDX[ 25]=FFXSR: 0x0 (0) // FXSAVE and FXRSTOR instruction optimizations. EDX[ 26]=Page1GB: 0x0 (0) // 1-GB large page support. EDX[ 27]=RDTSCP: 0x0 (0) // RDTSCP and TSC_AUX. EDX[ 29]=LM: 0x1 (1) // 64-bit long mode.(x86-64) EDX[ 30]=3DNowExt: 0x0 (0) // AMD extensions to 3DNow! instructions. EDX[ 31]=3DNow: 0x0 (0) // 3DNow! instructions. 0x80000002[0]: 20202020 49202020 6C65746E 20295228 0x80000003[0]: 65726F43 294D5428 2D336920 30313332 0x80000004[0]: 5043204D 20402055 30312E32 007A4847 Brand: Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz 0x80000005[0]: 00000000 00000000 00000000 00000000 EAX[ 7: 0]=L1ITlb2and4MSize: 0x0 (0) // Instruction TLB number of entries for 2-MB and 4-MB pages. EAX[15: 8]=L1ITlb2and4MAssoc: 0x0 (0) // Instruction TLB associativity for 2-MB and 4-MB pages. EAX[23:16]=L1DTlb2and4MSize: 0x0 (0) // Data TLB number of entries for 2-MB and 4-MB pages. EAX[31:24]=L1DTlb2and4MAssoc: 0x0 (0) // Data TLB associativity for 2-MB and 4-MB pages. EBX[ 7: 0]=L1ITlb4KSize: 0x0 (0) // Instruction TLB number of entries for 4 KB pages. EBX[15: 8]=L1ITlb4KAssoc: 0x0 (0) // Instruction TLB associativity for 4KB pages. EBX[23:16]=L1DTlb4KSize: 0x0 (0) // Data TLB number of entries for 4 KB pages. EBX[31:24]=L1DTlb4KAssoc: 0x0 (0) // Data TLB associativity for 4 KB pages. ECX[ 7: 0]=L1DcLineSize: 0x0 (0) // L1 data cache line size in bytes. ECX[15: 8]=L1DcLinesPerTag: 0x0 (0) // L1 data cache lines per tag. ECX[23:16]=L1DcAssoc: 0x0 (0) // L1 data cache associativity. ECX[31:24]=L1DcSize: 0x0 (0) // L1 data cache size in KB. EDX[ 7: 0]=L1IcLineSize: 0x0 (0) // L1 instruction cache line size in bytes EDX[15: 8]=L1IcLinesPerTag: 0x0 (0) // L1 instruction cache lines per tag. EDX[23:16]=L1IcAssoc: 0x0 (0) // L1 instruction cache associativity. EDX[31:24]=L1IcSize: 0x0 (0) // L1 instruction cache size KB. 0x80000006[0]: 00000000 00000000 01006040 00000000 EAX[11: 0]=L2ITlb2and4MSize: 0x0 (0) // L2 instruction TLB number of entries for 2 MB and 4 MB pages. EAX[15:12]=L2ITlb2and4MAssoc: 0x0 (0) // L2 instruction TLB associativity for 2 MB and 4 MB pages. EAX[27:16]=L2DTlb2and4MSize: 0x0 (0) // L2 data TLB number of entries for 2 MB and 4 MB pages. EAX[31:28]=L2DTlb2and4MAssoc: 0x0 (0) // L2 data TLB associativity for 2 MB and 4 MB pages. EBX[11: 0]=L2ITlb4KSize: 0x0 (0) // L2 instruction TLB number of entries for 4 KB pages. EBX[15:12]=L2ITlb4KAssoc: 0x0 (0) // L2 instruction TLB associativity for 4 KB pages. EBX[27:16]=L2DTlb4KSize: 0x0 (0) // L2 data TLB number of entries for 4 KB pages. EBX[31:28]=L2DTlb4KAssoc: 0x0 (0) // L2 data TLB associativity for 4 KB pages. ECX[ 7: 0]=L2LineSize: 0x40 (64) // L2 cache line size in bytes. ECX[11: 8]=L2LinesPerTag: 0x0 (0) // L2 cache lines per tag. ECX[15:12]=L2Assoc: 0x6 (6) // L2 cache associativity. ECX[31:16]=L2Size: 0x100 (256) // L2 cache size in KB. EDX[ 7: 0]=L3LineSize: 0x0 (0) // L3 cache line size in bytes. EDX[11: 8]=L3LinesPerTag: 0x0 (0) // L3 cache lines per tag. EDX[15:12]=L3Assoc: 0x0 (0) // L3 cache associativity. EDX[31:18]=L3Size: 0x0 (0) // L3 cache size. 0x80000007[0]: 00000000 00000000 00000000 00000000 EDX[ 0]=TS: 0x0 (0) // Temperature sensor. EDX[ 1]=FID: 0x0 (0) // Frequency ID control. EDX[ 2]=VID: 0x0 (0) // Voltage ID control. EDX[ 3]=TTP: 0x0 (0) // THERMTRIP. EDX[ 4]=HTC: 0x0 (0) // TM: Hardware thermal control (HTC). EDX[ 6]=100MHzSteps: 0x0 (0) // 100 MHz multiplier Control. EDX[ 7]=HwPstate: 0x0 (0) // Hardware P-state control. EDX[ 8]=TscInvariant: 0x0 (0) // TSC invariant. EDX[ 9]=CPB: 0x0 (0) // Core performance boost. EDX[ 10]=EffFreqRO: 0x0 (0) // Read-only effective frequency interface. 0x80000008[0]: 00003024 00000000 00000000 00000000 EAX[ 7: 0]=PhysAddrSize: 0x24 (36) // Maximum physical byte address size in bits. EAX[15: 8]=LinAddrSize: 0x30 (48) // Maximum linear byte address size in bits. EAX[23:16]=GuestPhysAddrSize: 0x0 (0) // Maximum guest physical byte address size in bits. ECX[ 7: 0]=NC: 0x0 (0) // number of physical cores - 1. ECX[15:12]=ApicIdCoreIdSize: 0x0 (0) // APIC ID size. The number of bits in the initial APIC20[ApicId] value that indicate core ID within a processor.
参考文献——
《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 3A, 3B, and 3C》044US. August 2012. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
《Intel® Architecture Instruction Set Extensions Programming Reference》014. AUGUST 2012. http://software.intel.com/en-us/avx/
《Intel® Processor Identification and the CPUID Instruction》. May 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
《AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions》. December 2011. http://support.amd.com/us/Processor_TechDocs/24594_APM_v3.pdf
《AMD CPUID Specification》. September 2010. http://support.amd.com/us/Embedded_TechDocs/25481.pdf
《x86 architecture CPUID》. http://www.sandpile.org/x86/cpuid.htm
《Haswell New Instruction Descriptions Now Available! 》. Mark Buxton. http://software.intel.com/en-us/blogs/2011/06/13/haswell-new-instruction-descriptions-now-available/
[IDF2012]ARCS002《Introduction to the upcoming Intel® Advanced Vector Extensions 2 (Intel® AVX2)》. 王有伟, Henry Ou. 2012-4.
[IDF2012]ARCS002《即将推出的英特尔® 高级矢量扩展指令集2(英特尔® AVX2)介绍》. 王有伟, Henry Ou. 2012-4.
《x86/x64 指令系统》. mik(邓志). http://www.mouseos.com/x64/default.html
《[x86]SIMD指令集发展历程表(MMX、SSE、AVX等)》. http://www.cnblogs.com/zyl910/archive/2012/02/26/x86_simd_table.html
《如何在各个版本的VC及64位下使用CPUID指令》. http://www.cnblogs.com/zyl910/archive/2012/05/21/vcgetcpuid.html
《[VC兼容32位和64位] 检查MMX和SSE系列指令集的支持级别》. http://www.cnblogs.com/zyl910/archive/2012/05/25/checksimd64.html
《[VC] CPUIDFIELD:CPUID字段的统一编号、读取方案。范例:检查SSE4A、AES、PCLMULQDQ指令》. http://www.cnblogs.com/zyl910/archive/2012/06/29/getcpuidfield.html
《[VC] 检测AVX系列指令集的支持级别(AVX、AVX2、F16C、FMA、FMA4、XOP)》. http://www.cnblogs.com/zyl910/archive/2012/07/04/checkavx.html
《[C#] cmdarg_ui:“简单参数命令行程序”的通用图形界面》. http://www.cnblogs.com/zyl910/archive/2012/06/19/cmdarg_ui.html
《[C/C++] 显示各种C/C++编译器的预定义宏(C11标准、C++11标准、VC、BCB、Intel、GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/02/printmacro.html
《[C] 让VC、BCB支持C99的整数类型(stdint.h、inttypes.h)(兼容GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/08/c99int.html
《GCC 64位程序的makefile条件编译心得——32位版与64位版、debug版与release版(兼容MinGW、TDM-GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/14/gcc64_make.html
《[C] 在GCC中获取CPUID信息(兼容VC)》. http://www.cnblogs.com/zyl910/archive/2012/08/06/getcpuid_gcc.html
《ccpuid:CPUID信息模块。范例:显示所有的CPUID信息》. http://www.cnblogs.com/zyl910/archive/2012/07/11/ccpuid.html
《ccpuid:CPUID信息模块 V1.01版,支持GCC(兼容32位或64位的Windows/Linux)》. http://www.cnblogs.com/zyl910/archive/2012/08/22/ccpuid_v101.html