怎样取得双核CPU的序列号??? ( 积分: 200 )

  • 主题发起人 主题发起人 唐佐平
  • 开始时间 开始时间

唐佐平

Unregistered / Unconfirmed
GUEST, unregistred user!
用单核CPU的汇编指令取得的CPU序列号在双核CPU上执行结果都是一样的,
请大家帮忙解决下面两个问题:
1、怎样判断是单核CPU还是双核CPU?
2、双核CPU的序列号怎样取得?
谢谢大家。
 
好像在p3后没有唯一的序列号了吧?
 
{$A+,R-,Z1}

unit HT_Dual;

interface

uses
Windows, Messages, SysUtils, Classes, Dialogs, Grids;

const
MASK_HTT = $10000000; // Hyper-Threading Technology
MASK_NUMLOGICALS = $00FF0000; // Number of logical processors
MASK_APICID = $FF000000; // APIC Id
MASK_CACHETYPE = $0000001F; // L2 Cache type
MASK_CACHELEVEL = $000000E0; // L2 Cache level
MASK_CACHETHREADS = $03FFC000; // Number of threads in L2 Cache
MASK_CACHELINESIZE = $00000FFF; // L2 Cache line size
MASK_CACHEPARTITIONS = $003FF000; // L2 Cache partitions
MASK_CACHEWAYS = $FFC00000; // L2 Cache ways of associativity
CACHETYPE_NULL = 0;
CACHETYPE_DATA = 1;
CACHETYPE_INSTRUCTION = 2;
CACHETYPE_UNIFIED = 3;
SHFT_CACHELEVEL = 5;
SHFT_CACHEPARTITIONS = 12;
SHFT_CACHETHREADS = 14;
SHFT_NUMLOGICALS = 16;
SHFT_CACHEWAYS = 22;
SHFT_APICID = 24;

type
TApicId = record
Physical: integer; // Id of the physical processor
Logical : integer; // Id of the logical processor
end;

TCacheInfo = record
cType : integer; // Cache type (i.e. instruction, data, unified)
cLevel : integer; // Cache level (1 to n)
cSize : integer; // Size of the cache in bytes
cThreads: integer; // Number of threads sharing the cache
end;

TCpuHTInfo = record
MaxCPUIDBasicInput: integer; // Maximum basic input supported by CPUID
bHTTechnology: BOOL; // Signifies support for HT Technology
id: TApicId;
aCacheInfo: array[0..4] of TCacheInfo;
end;

THTCPUID = class
private
m_ProcessMask: Word;
m_cProcessors: integer;

protected
{ Detects and returns the processor information using CPUID. }
function GetCPUIDInfo(var HTInfo: TCpuHTInfo): BOOL; virtual;

{ These functions contain OS specific APIs. }
function GetProcessMask: Word;
function SetProcessMask(const BitMask: Word): BOOL;

public
constructor Create; virtual;
destructor Destroy; override;

{ Initialize the array of CPUHTInfo structures. }
function Initialize: BOOL; virtual;

{ Returns the number of processors in the system. }
function GetProcessorCount: Word;

{ Returns the detetced processor info for each processor. }
function GetProcessorInfo(Index: Word; var HTInfo: TCpuHTInfo): BOOL; virtual;
end;

var
HTCPUID: THTCPUID;

procedure ShowHTInfo(StrGrid: TStringGrid);

implementation

function cpu_id: DWORD;
asm
db 0fh // Hardcoded CPUID instruction
db 0a2h
end;

procedure ShowHTInfo(StrGrid: TStringGrid);
type
Str3 = array[0..2] of Char;
Str8 = array[0..11] of Char;
var
HTInfo: TCpuHTInfo;
CPU, j, maxJ, c, r,
cProcessors: integer;
cStr: Str8;
const
BoolStr: array[False..True] of Str3= ('No', 'Yes');
szHeader: array[0..8] of ShortString= (
'CPU', 'Max. CPUID Input', 'HT Support', 'Physical', 'Logical',
'Type', 'Level', 'Size', 'Threads');
begin
HTCPUID:= THTCPUID.Create;
try
with HTCPUID, StrGrid do
if Initialize then
begin
RowCount:= 2;
for c:= 0 to 8 do
Cells[c, 0]:= szHeader[c];

{ Get the number of processors and initialize an array to hold the data. }
cProcessors:= GetProcessorCount;

//RowCount:= RowCount - 1;
r:= 0;
for CPU:= 0 to cProcessors - 1 do
begin
Inc(r);
RowCount:= r+1;
{ Get the information for the processor. }
GetProcessorInfo(CPU, HTInfo);

{ Display the processor information. }
maxJ:= SizeOf(HTInfo.aCacheInfo) div SizeOf(HTInfo.aCacheInfo[0]);
for j:= 0 to maxJ - 1 do
if (HTInfo.aCacheInfo[j].cLevel = 2) then
Break;

if HTInfo.aCacheInfo[j].cType = CACHETYPE_NULL then
cStr:= 'Null';
if HTInfo.aCacheInfo[j].cType = CACHETYPE_DATA then
cStr:= 'Data';
if HTInfo.aCacheInfo[j].cType = CACHETYPE_INSTRUCTION then
cStr:= 'Instruction';
if HTInfo.aCacheInfo[j].cType = CACHETYPE_UNIFIED then
cStr:= 'Unified';

Cells[0, r]:= IntToStr(CPU);
Cells[1, r]:= IntToStr(HTInfo.MaxCPUIDBasicInput);
Cells[2, r]:= BoolStr[HTInfo.bHTTechnology];
if HTInfo.bHTTechnology then
begin
Cells[3, r]:= IntToStr(HTInfo.Id.Physical);
Cells[4, r]:= IntToStr(HTInfo.Id.Logical);
Cells[5, r]:= cStr;
Cells[6, r]:= IntToStr(HTInfo.aCacheInfo[j].cLevel);
Cells[7, r]:= IntToStr(HTInfo.aCacheInfo[j].cSize shr 10);
Cells[8, r]:= IntToStr(HTInfo.aCacheInfo[j].cThreads);
end else
begin
for c:= 3 to 8 do
Cells[c, r]:= 'n/a';
end;
end;
end else
begin
MessageDlg('Error in detection.', mtError, [mbOK], 0);
end;
finally
HTCPUID.Free;
end;
end;

constructor THTCPUID.Create;
begin
m_ProcessMask:= 0;
m_cProcessors:= 0;
end;

destructor THTCPUID.Destroy;
begin
inherited Destroy;
end;

function THTCPUID.Initialize: BOOL;
var
Mask: Word;
i, cBits: integer;
begin
result:= False;

{ Get the processor mask for the process. }
m_ProcessMask:= GetProcessMask;
if m_ProcessMask > 0 then
begin

{ Count the number of bits in the mask. }
Mask:= m_ProcessMask;
cBits:= SizeOf(m_ProcessMask) * 8;
for i:= 0 to cBits - 1 do
begin
if BOOL(Mask and 1) then
Inc(m_cProcessors);
Mask:= Mask shr 1;
end;
result:= True;
end;
end;

function THTCPUID.GetProcessorCount: Word;
begin
result:= m_cProcessors;
end;

function THTCPUID.GetProcessorInfo(Index: Word; var HTInfo: TCpuHTInfo): BOOL;
var
Bit: Word;
i, cBits: integer;
CurrIndex: integer;
begin
result:= False;

if BOOL(m_ProcessMask and Index < m_cProcessors) then
begin
{ Search through the bits to find the index selected. }
Bit:= 1;
cBits:= SizeOf(m_ProcessMask) * 8;
CurrIndex:= -1;
for i:= 0 to cBits - 1 do
begin
{ A bit exists in the spot, so increment the current index. }
if BOOL(m_ProcessMask and Bit) then
Inc(CurrIndex);

{ The current index is equal to the index so this is the one we process. }
if (CurrIndex = Index) then
begin
SetProcessMask( Bit );
GetCPUIDInfo(HTInfo);
SetProcessMask( m_ProcessMask );
break;
end;
Bit:= Bit shl 1;
end;
result:= True;
end;
end;

function THTCPUID.GetCPUIDInfo(var HTInfo: TCpuHTInfo): BOOL;
const
szIntelId: array[0..11] of Char= 'GenuineIntel';
var
CacheInfoSize: integer;
bSuccessful: BOOL;
iCacheInfo: integer;
begin
CacheInfoSize:= SizeOf(TCacheInfo);
bSuccessful:= False;
iCacheInfo:= 0;
ZeroMemory(@HTInfo, SizeOf(TCpuHTInfo));
try
asm
{ Get the initial basic information (CPUID.0). }
mov eax, 0
call cpu_id

{ Check for an Intel processor. }
mov edi, offset szIntelId
cmp ebx, [edi]
jne @Quit
cmp edx, [edi+4]
jne @Quit
cmp ecx, [edi+8]
jne @Quit

{ Set to successful since this is an Intel processor. }
mov bSuccessful, 1

{ Save the maximum CPUID basic information level supported. }
mov esi, HTInfo
mov TCpuHTInfo[esi].MaxCPUIDBasicInput, eax

{ Get the basic CPU information (CPUID.1). }
cmp TCpuHTInfo[esi].MaxCPUIDBasicInput, 1
jl @Quit
mov eax, 1
call cpu_id

{ Check for HT Technology }
test edx, MASK_HTT
jz @Quit
mov TCpuHTInfo[esi].bHTTechnology, 1

{ Calculate the APIC ID. }
mov eax, ebx
and eax, MASK_NUMLOGICALS
shr eax, SHFT_NUMLOGICALS
and ebx, MASK_APICID
shr ebx, SHFT_APICID
mov edi, 1
mov edx, $FF // Physical id mask
xor ecx, ecx // Physical id shift
@GetApicId:
cmp edi, eax
jge @EndApicId
shl edi, 1
shl edx, 1
add ecx, 1
jmp @GetApicId
@EndApicId:
lea edi, TCpuHTInfo[esi].Id
mov eax, ebx
and ebx, edx
shr ebx, cl
mov TCpuHTInfo[edi].Id.Physical, ebx
not edx
and eax, edx
mov TCpuHTInfo[edi].Id.Logical, eax

{ Get the cache size and sharing information (CPUID.4) }
cmp TCpuHTInfo[esi].MaxCPUIDBasicInput, 4
jl @Quit
lea edi, TCpuHTInfo[esi].aCacheInfo
@GetCacheInfo:
mov eax, 4
mov ecx, iCacheInfo
call cpu_id

{ Check for end of descriptors (0 cache type). }
test eax, MASK_CACHETYPE
jz @EndCacheInfo
mov edx, eax

{ Get the cache type. }
and eax, MASK_CACHETYPE
mov TCacheInfo[edi].cType, eax

{ Get the cache level. }
mov eax,edx
and eax, MASK_CACHELEVEL
shr eax, SHFT_CACHELEVEL
mov TCacheInfo[edi].cLevel, eax

{ Get the number of threads sharing this cache. }
and edx, MASK_CACHETHREADS
shr edx, SHFT_CACHETHREADS
add edx, 1
mov TCacheInfo[edi].cThreads, edx

{ Calculate the size of the cache. }
mov eax, ebx
xor edx, edx
and eax, MASK_CACHELINESIZE
add eax, 1
add ecx, 1
mul ecx
mov ecx, ebx
and ebx, MASK_CACHEPARTITIONS
shr ebx, SHFT_CACHEPARTITIONS
add ebx, 1
mul ebx
and ecx, MASK_CACHEWAYS
shr ecx, SHFT_CACHEWAYS
add ecx, 1
mul ecx
mov TCacheInfo[edi].cSize, eax

{ Go to the next cache. }
add edi, CacheInfoSize
add iCacheInfo, 1
jmp @GetCacheInfo
@EndCacheInfo:

@Quit:
end;
except
raise;
end;
result:= bSuccessful;
end;

function THTCPUID.GetProcessMask: Word;
var
ProcessAffinityMask,
SystemAffinityMask: DWORD;
begin
if(GetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask, SystemAffinityMask)) then
result:= Word(ProcessAffinityMask) else
result:= 0;
end;

function THTCPUID.SetProcessMask(const BitMask: Word): BOOL;
var
ProcessAffinityMask: DWORD;
begin
ProcessAffinityMask:= BitMask;
if (SetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask)) then
begin
Sleep(0);
result:= True;
end else
result:= False;
end;

end.
 
CPU 核心数:
function CpuCoreNumber: word;
var
_ebx: Longword;
dimm: string;
begin
asm
mov eax,1
db $0F,$A2
mov _ebx,ebx
end;
result:=lo(_ebx shr 16);
end;

CPU ID 在 P3 以后都是 disabled,无法取得。
 

Similar threads

I
回复
0
查看
503
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
761
import
I
后退
顶部