2,640
社区成员
发帖
与我相关
我的任务
分享
#include <windows.h>
#include <intrin.h>
#include <stdio.h>
typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
// Helper function to count set bits in the processor mask.
DWORD CountSetBits(ULONG_PTR bitMask)
{
DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
DWORD bitSetCount = 0;
ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
DWORD i;
for (i = 0; i <= LSHIFT; ++i)
{
bitSetCount += ((bitMask & bitTest)?1:0);
bitTest/=2;
}
return bitSetCount;
}
//cpu信息结构体
typedef struct _cpuinfo
{
char CPUString[0x20];
char CPUBrandString[0x40];
DWORD logicalProcessorCount;
DWORD numaNodeCount;
DWORD processorCoreCount;
DWORD processorL1CacheCount;
DWORD processorL2CacheCount;
DWORD processorL3CacheCount;
DWORD processorPackageCount;
}cpuinfo;
//返回CPU信息结构体
cpuinfo GetCPUInfo() {
LPFN_GLPI glpi;
BOOL done = FALSE;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
DWORD returnLength = 0;
cpuinfo mycpu = {0,0,0,0,0,0,0};
DWORD byteOffset = 0;
PCACHE_DESCRIPTOR Cache;
int CPUInfo[4] = {-1};
__cpuid(CPUInfo, 0);
memset(mycpu.CPUString, 0, sizeof(mycpu.CPUString));
*((int*)mycpu.CPUString) = CPUInfo[1];
*((int*)(mycpu.CPUString+4)) = CPUInfo[3];
*((int*)(mycpu.CPUString+8)) = CPUInfo[2];
char CPUBrandString[0x40];
__cpuid(CPUInfo, 0x80000000);
unsigned nExIds = CPUInfo[0];
memset(CPUBrandString, 0, sizeof(CPUBrandString));
for (unsigned i=0x80000000; i<=nExIds; ++i)
{
__cpuid(CPUInfo, i);
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
}
//将去年开头空格的字符串复制进结构体
bool spaceinfront = true;
int num = 0;
for(char *pch = CPUBrandString; *pch != '\0';pch++)
{
if(*pch == ' ' && spaceinfront)
continue;
else
{
spaceinfront = false;
mycpu.CPUBrandString[num++] = *pch;
}
}
mycpu.CPUBrandString[num] = '\0';
glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"GetLogicalProcessorInformation");
//if (NULL == glpi)
//GetLogicalProcessorInformation is not supported.
while (!done)
{
DWORD rc = glpi(buffer, &returnLength);
if (FALSE == rc)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer)
free(buffer);
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(returnLength);
//if (NULL == buffer)
//ErrorAllocation failure
}
else
{
//Error: GetLastError()
}
}
else
{
done = TRUE;
}
}
ptr = buffer;
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
{
switch (ptr->Relationship)
{
case RelationNumaNode:
// Non-NUMA systems report a single record of this type.
mycpu.numaNodeCount++;
break;
case RelationProcessorCore:
mycpu.processorCoreCount++;
// A hyperthreaded core supplies more than one logical processor.
mycpu.logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
break;
case RelationCache:
// Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
Cache = &ptr->Cache;
if (Cache->Level == 1)
{
mycpu.processorL1CacheCount++;
}
else if (Cache->Level == 2)
{
mycpu.processorL2CacheCount++;
}
else if (Cache->Level == 3)
{
mycpu.processorL3CacheCount++;
}
break;
case RelationProcessorPackage:
// Logical processors share a physical package.
mycpu.processorPackageCount++;
break;
default:
//Error: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.
break;
}
byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
ptr++;
}
free(buffer);
return mycpu;
}
int main() {
cpuinfo ci;
ci=GetCPUInfo();
printf("CPUString :%s\n",ci.CPUString );
printf("CPUBrandString :%s\n",ci.CPUBrandString );
printf("logicalProcessorCount:%d\n",ci.logicalProcessorCount);
printf("numaNodeCount :%d\n",ci.numaNodeCount );
printf("processorCoreCount :%d\n",ci.processorCoreCount );
printf("processorL1CacheCount:%d\n",ci.processorL1CacheCount);
printf("processorL2CacheCount:%d\n",ci.processorL2CacheCount);
printf("processorL3CacheCount:%d\n",ci.processorL3CacheCount);
printf("processorPackageCount:%d\n",ci.processorPackageCount);
return 0;
}
#pragma optimize("",off)
BOOL CCPUTicker::CheckHasRDTSC()
{
SYSTEM_INFO sys_info;
GetSystemInfo(&sys_info);
if (sys_info.dwProcessorType==PROCESSOR_INTEL_PENTIUM)
{
try
{
_asm
{
_emit 0x0f ; rdtsc
_emit 0x31
}
}
catch (...) // Check to see if the opcode is defined.
{
TRACE0("RDTSC instruction NOT present.\n");
return FALSE;
}
// Check to see if the instruction ticks accesses something that changes.
volatile ULARGE_INTEGER ts1,ts2;
_asm
{
xor eax,eax
_emit 0x0f ; cpuid
_emit 0xa2
_emit 0x0f ; rdtsc
_emit 0x31
mov ts1.HighPart,edx
mov ts1.LowPart,eax
xor eax,eax
_emit 0x0f ; cpuid
_emit 0xa2
_emit 0x0f ; rdtsc
_emit 0x31
mov ts2.HighPart,edx
mov ts2.LowPart,eax
}
// If we return true then there's a very good chance it's a real RDTSC instruction!
if (ts2.HighPart==ts1.HighPart)
{
if (ts2.LowPart>ts1.LowPart)
{
TRACE0("RDTSC instruction probably present.\n");
return TRUE;
}
else
{
TRACE0("RDTSC instruction NOT present.\n");
return FALSE;
}
}
else if (ts2.HighPart>ts1.HighPart)
{
TRACE0("RDTSC instruction probably present.\n");
return TRUE;
}
else
{
TRACE0("RDTSC instruction NOT present.\n");
return FALSE;
}
}
else
{
TRACE0("RDTSC instruction NOT present.\n");
return FALSE;
}
}
#pragma optimize("",on)