2007-1-23 13:42
skyjacker
如何获取多核、多cpu系统中指定cpu的序列号
如何获取多核、多cpu系统中指定cpu的序列号
[url=http://www.cnpack.org]http://www.cnpack.org[/url]
CnPack IV QQ Group: 130970
2007-01-23
感谢:Passion,Bahamut,早安,空气,SkyJacker...
没有Bahamut的奇思妙点,就没有这片文章。
在多cpu、多核中,会随机的获得不同的序列号.
这就为我们根据cpu序列号来制作注册机带来了很大的麻烦。
Windows 2000/xp允许设置进程和线程的亲缘性。
换句话说,可以控制哪个C P U能够运行某些线程。这称为硬亲缘性。
Windows提供了设置亲缘性的函数SetProcessAffinityMask 。
使用它来控制获取指定cpu的序列号。
本文分为2部分:
1、如何获得cpu的序列号。
2、如何获取指定cpu或指定cpu核的序列号。
1、如何获得cpu的序列号。
使用cpuid指令来获取。
在调用CPUID之前,EAX中存放的是功能代码。
在调用CPUID之后,EAX,EBX,ECX,EDX存放的是CPU的各种特征信息。
这些信息也就是我们通常所说的CPU序列号。
mov eax, 0 //获取制造商信息
cpuid
mov eax, 1 //获得CPU的序列号
cpuid
以下三个函数,可供参考:
function NewCPUID: string;
const
CPUINFO = 'CPU制造商: %S 序列号: %x';
var
s: array[0..19] of Char;
MyCpuID: Integer;
begin
FillChar(s, 20, 0);
asm
push ebx
push ecx
push edx
mov eax, 0
cpuid
mov dword ptr s[0], ebx
mov dword ptr s[4], edx
mov dword ptr s[8], ecx
mov eax, 1
cpuid
mov MyCpuID, edx
pop edx
pop ecx
pop ebx
end;
Result := Format(CPUINFO, [s, MyCpuID]);
end;
function GetCPUID: TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI, EAX [email={@Resukt]{@Resukt[/email]}
MOV EAX, 1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX, EBX
STOSD {CPUID[2]}
MOV EAX, ECX
STOSD {CPUID[3]}
MOV EAX, EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
end;
获取cpu的序列号:
function GetCnCPUID(): string;
const
CPUINFO = '%.8x-%.8x-%.8x-%.8x';
var
iEax: Integer;
iEbx: Integer;
iEcx: Integer;
iEdx: Integer;
begin
asm
push ebx
push ecx
push edx
mov eax, 1
DW $A20F//cpuid
mov iEax, eax
mov iEbx, ebx
mov iEcx, ecx
mov iEdx, edx
pop edx
pop ecx
pop ebx
end;
Result := Format(CPUINFO, [iEax, iEbx, iEcx, iEdx]);
end;
2、如何获取指定cpu或指定cpu核的序列号。
根据Windows可以设置进程和线程的亲缘性的特点,使用SetProcessAffinityMask函数,
来控制哪个cpu来运行获取序列号的进程,因此也就获取了指定的cpu的序列号。
为了和单cpu兼容,建议总是获取第一个cpu的序列号。
procedure SetCPU(h: THandle;CpuNo: Integer);
//CpuNo:决定了获得第几个cpu内核的第几个序列号。
var
ProcessAffinity: Cardinal;
_SystemAffinity: Cardinal;
begin
GetProcessAffinityMask(h, ProcessAffinity, _SystemAffinity) ;
ProcessAffinity := CpuNo; //this sets the process to only run on CPU 0
//for CPU 1 only use 2 and for CPUs 1 & 2 use 3
SetProcessAffinityMask(h, ProcessAffinity)
end;
使用方法:
SetCPU(GetCurrentProcess,1); //第一个cpu的第一个cpu内核
ShowMessage(GetCnCPUID);
如果要更灵活的操作,可以通过注册表来获取cpu的数量:
在注册表下:
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
后记:这片文章源于CnPack 群里关于获取多核CPU的ID的问题讨论。
感谢CnPack 群里的所有成员。
BS下"早安空气",竟然说“你在你短暂的生命里花大量的时间去做这个没有价值的事情”-_-!!超级BS、BS、BS……^_^
for I:=0 to 10000000000000000000000000000 do
BS;
附录“早安空气”语录:
"放弃吧,API不适合你"
"你在你短暂的生命里花大量的时间去做这个没有价值的事情"
[[i] 本帖最后由 skyjacker 于 2007-1-23 16:38 编辑 [/i]]
2007-1-23 13:49
Passion
貌似现在发技术帖都习惯顺便bs水版板“早安空气”:lol
2007-1-23 13:52
bahamut8348
多BS下是好事啊,后后:loveliness:
这就充分证明了空气的知名度啊
还有,这个不是我的奇思妙点,而是在客户那里遇到的问题,其实偶很懒滴:P
2007-1-23 14:25
kendling
支持支持。。。
2007-1-26 15:34
koalaone
bs下
2007-2-1 20:43
zzzl
:lol 最后的那个哪是附录?根本就是参考文献嘛
2007-2-2 11:14
Passion
还好不是鸣谢。
2007-2-5 21:44
kendling
哈哈,什么变鸣谢了?
2007-2-5 22:11
skyjacker
类似于熊猫烧香鸣谢单位:
卡巴
瑞兴
蒋民
........
2007-2-6 00:53
kendling
:lol: :lol:
不错不错。
2007-11-24 14:13
wangdragon
上面的取CPU有问题,发一下Bahamut的函数
function GetCPUID: TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI, EAX {@Resukt}
MOV EAX, 1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX, EBX
STOSD {CPUID[2]}
MOV EAX, ECX
STOSD {CPUID[3]}
MOV EAX, EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
end;
function GetCPUIDStr: string; //返回CPU序列号
var
CPUID: TCPUID;
ProcessAffinity, _SystemAffinity: Cardinal;
begin
GetProcessAffinityMask(GetCurrentProcess, ProcessAffinity, _SystemAffinity);
SetProcessAffinityMask(GetCurrentProcess, 1);
CPUID:= GetCPUID;
Result:= IntToHex(CPUID[1], 2) + '-' +
IntToHex(CPUID[2], 2) + '-' +
IntToHex(CPUID[3], 2) + '-' +
IntToHex(CPUID[4], 2);
SetProcessAffinityMask(GetCurrentProcess, ProcessAffinity);
end;
2007-11-26 14:58
skyjacker
谢谢
最终版本在 cnpack\Source\Common\CnHardWareInfo.pas 中的 TCnCpuId
在 cnpack\Examples 中有 Demo CnCpuID.
欢迎测试
2008-6-18 10:56
wsc188
急!!~救命呀..
procedure SetCPU(h: THandle;CpuNo: Integer);
//CpuNo:决定了获得第几个cpu内核的第几个序列号。
var
ProcessAffinity: Cardinal;
_SystemAffinity: Cardinal;
begin
GetProcessAffinityMask(h, ProcessAffinity, _SystemAffinity) ;
ProcessAffinity := CpuNo; //this sets the process to only run on CPU 0
//for CPU 1 only use 2 and for CPUs 1 & 2 use 3
SetProcessAffinityMask(h, ProcessAffinity)
end;
使用方法:
SetCPU(GetCurrentProcess,1); //第一个cpu的第一个cpu内核
我怎么在主程序用了..SetCPU(GetCurrentProcess,1);
在退出程序时.就像死机一样慢的呀,.!~
哪个可以说下是怎么回事吗?
多谢!~~
2008-6-18 20:27
bahamut8348
LS的,跟个断点,看看执行在什么地方慢
页:
[1]
Powered by Discuz! Archiver 5.0.0
© 2001-2006 Comsenz Inc.