[阅读: 407] 2006-04-20 02:03:22
#include <string.h>
#include <stdio.h>
struct cpuid_struct {
unsigned _eax;
unsigned _ebx;
unsigned _ecx;
unsigned _edx;
};
void cpuid(cpuid_struct * pCpuId)
{
#ifdef __GNUC__
__asm __volatile("cpuid"
: "=a"(pCpuId->_eax), "=b"(pCpuId->_ebx), "=c"(pCpuId->_ecx), "=d"(pCpuId->_edx)
: "a"(pCpuId->_eax), "b"(pCpuId->_ebx), "c"(pCpuId->_ecx), "d"(pCpuId->_edx)
);
#elif defined(_MSC_VER) || defined (__BORLANDC__)
_asm {
PUSH ESI
MOV ESI, pCpuId
MOV EAX, [ESI]cpuid_struct._eax
MOV EBX, [ESI]cpuid_struct._ebx
MOV ECX, [ESI]cpuid_struct._ecx
MOV EDX, [ESI]cpuid_struct._edx
CPUID
MOV [ESI]cpuid_struct._eax, EAX
MOV [ESI]cpuid_struct._ebx, EBX
MOV [ESI]cpuid_struct._ecx, ECX
MOV [ESI]cpuid_struct._edx, EDX
POP ESI
}
#endif
} // cpuid
#define AMD_CPU_ID "AuthenticAMD"
#define INTEL_CPU_ID "GenuineIntel"
int main()
{
struct cpuid_struct c;
// Get CPU Vendor id
c._eax = 0;
cpuid(&c);
char cpuVendorId[4 * 3 + 1];
memcpy(cpuVendorId, &(c._ebx), 4);
memcpy(cpuVendorId + 4, &(c._edx), 4);
memcpy(cpuVendorId + 8, &(c._ecx), 4);
cpuVendorId[4 * 3] = 0;
printf("CPU: %s\n", cpuVendorId);
// Maximum standard function
unsigned long maxStandardFunction = c._eax;
unsigned long httPerCore = 1;
unsigned long corePerProcessor = 1;
// AMD:
if ( strcmp(cpuVendorId, AMD_CPU_ID) == 0 ) {
c._eax = 1;
cpuid(&c);
unsigned AMD_HTT = c._edx & 0x10000000;
unsigned AMD_Logical_Processor_Count = (c._ebx & 0x00ff0000) >> 16;
c._eax = 0x80000001;
cpuid(&c);
unsigned AMD_Cmp_Legacy = c._ecx & 2;
c._eax = 0x80000008;
cpuid(&c);
unsigned AMD_NC = c._ecx & 0xFF;
// Summary:
if ( !AMD_HTT ) {
httPerCore = 1;
corePerProcessor = 1;
}
else {
if ( AMD_Cmp_Legacy ) {
httPerCore = 1;
corePerProcessor = AMD_NC + 1;
}
else {
corePerProcessor = AMD_NC + 1;
httPerCore = AMD_Logical_Processor_Count / corePerProcessor;
}
}
} // AMD
// Intel:
if ( strcmp(cpuVendorId, INTEL_CPU_ID) == 0 ) {
c._eax = 1;
cpuid(&c);
unsigned INTEL_HTT = c._edx & 0x10000000;
unsigned INTEL_Logical_Processor_Count = (c._ebx & 0x00ff0000) >> 16;
printf("maxStandardFunction = %d, INTEL_HTT = 0x%x, INTEL_Logical_Processor_Count = %d\n",
maxStandardFunction, INTEL_HTT, INTEL_Logical_Processor_Count);
if ( maxStandardFunction >= 4 ) {
c._eax = 4;
c._ecx = 0;
cpuid(&c);
unsigned INTEL_CORE_PER_DIE = (c._eax & 0xfc000000) >> 26;
corePerProcessor = INTEL_CORE_PER_DIE + 1;
httPerCore = INTEL_Logical_Processor_Count / corePerProcessor;
printf("INTEL_HTT = 0x%x, INTEL_CORE_PER_DIE = %d, INTEL_Logical_Processor_Count = %d\n",
INTEL_HTT, INTEL_CORE_PER_DIE, INTEL_Logical_Processor_Count);
}
else {
if ( INTEL_HTT )
httPerCore = INTEL_Logical_Processor_Count;
else
httPerCore = 1;
corePerProcessor = 1;
}
} // Intel
printf("HyperThreading per core = %d, Core per processor = %d\n", httPerCore, corePerProcessor);
return 0;
}