如何从Delphi 64位应用程序(XE5)获得CPU速度?

时间:2014-02-13 14:35:05

标签: delphi 64-bit delphi-xe5

我们正在使用Delphi XE5将应用程序套件迁移到64位。在我们的约框中,我们显示CPU速度。我们当前使用的例程是32位汇编,因此不会在64位下编译。

是否有本机方法从Delphi 64位中检索CPU速度?

4 个答案:

答案 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)。

enter image description here

源代码可用,因此您可以根据需要将其扩展为访问其他WMI类。

如果您不想使用组件,则可以使用由"WMI Delphi code Creator"创建的工具Rodrigo Ruz来获取此属性所需的代码。

enter image description here

问候。