我们正在使用Delphi XE5将应用程序套件迁移到64位。在我们的约框中,我们显示CPU速度。我们当前使用的例程是32位汇编,因此不会在64位下编译。
是否有本机方法从Delphi 64位中检索CPU速度?
答案 0 :(得分:4)
如果您的平台是Windows并且您想要通告的CPU速度,那么您只需检查注册表中的HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\~MHz
DWORD值:
program SO21757165;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Registry,
Windows,
System.SysUtils;
function GetCPUSpeed : String;
var
Reg : TRegistry;
begin
Reg := TRegistry.Create(KEY_QUERY_VALUE);
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKeyReadOnly('HARDWARE\DESCRIPTION\System\CentralProcessor\0') then
begin
Result := Format('CPU Speed is %dMHz', [Reg.ReadInteger('~MHz')]);
Reg.CloseKey;
end;
finally
Reg.Free;
end;
end;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
Writeln(GetCPUSpeed);
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
修改强>
将上面的代码段重写为可编译的示例。此示例已在XE7中得到验证,适用于32位和64位环境(启用了UAC)
答案 1 :(得分:0)
注册表不是一个好的解决方案,因为它可能会被更改,并且可能受用户许可(读取注册表)。
以下代码可以在Delphi XE-8下编译,32位和64位,遵循SAME原则,因此这应该为您提供32位和64位的一致值。
{$IFDEF CPUX64}
function GetCpuClockCycleCount: Int64; assembler; register;
asm
dw 310Fh // rdtsc
shl rdx, 32
or rax, rdx
end;
{$ENDIF}
function GetCPUSpeed: double;
{$IFDEF CPUX86}
const
DelayTime = 500; // measure time in ms
var
TimerHi, TimerLo: DWOrd;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetthreadPriority(GetCurrentthread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetthreadPriority(GetCurrentthread, thread_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetthreadPriority(GetCurrentthread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;
{$ELSE}
const
DelayTime = 500;
var
x, y: UInt64;
PriorityClass, Priority: Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
x := GetCpuClockCycleCount;
Sleep(DelayTime);
y := GetCpuClockCycleCount;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := ((y - x) and $FFFFFFFF) / (1000 * DelayTime);
end;
{$ENDIF}
答案 2 :(得分:0)
从技术上讲,CPU中的每个核心都可以以不同的频率运行,您可以使用此WMI示例来获取每个“核心”的频率,尽管它会计算逻辑核心而非物理核心。
这是一个VCL示例
uses : ComObj,ActiveX;
procedure GetProcessorPerformanceInfo;
const
WbemUser ='';
WbemPassword ='';
WbemComputer ='localhost';
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
Form5.ListBox1.Clear;
Form5.Tfreq.Clear;
Form5.Tusage.Clear;
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\WMI', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM ProcessorPerformance','WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
Form5.ListBox1.Items.Add(Format('frequency %d',[Integer(FWbemObject.frequency)])+Format('%s',[String(FWbemObject.InstanceName)]));// Uint32
FWbemObject:=Unassigned;
end;
end;
有一个非常好的工具可以用来创建这些工具,这是使用来自https://theroadtodelphi.wordpress.com/wmi-delphi-code-creator/的Delphi WMI代码生成器
答案 3 :(得分:-1)
我认为您可以使用WMI访问此信息。
可在此网站(http://neftali.clubdelphi.com)或sourceforge(http://sourceforge.net/projects/glibwmi/)上找到GLibWMI组件。 当前版本为1.8b,并且有一个名为 TProcessorInfo 的组件,您可以使用该组件获取此信息。
它具有( CurrentclockSpeed 或 MaxClockSpeed )等属性。
该库附带的一个示例是关于此类(TProcessorInfo)。
源代码可用,因此您可以根据需要将其扩展为访问其他WMI类。
如果您不想使用组件,则可以使用由"WMI Delphi code Creator"创建的工具Rodrigo Ruz来获取此属性所需的代码。
问候。