目前我正在使用此功能。它工作正常,但每个查询大约需要1秒。所以在我的情况下,我在我的申请中浪费了3秒钟。目前我正在考虑使用3个线程在一秒钟内获取所有信息。
function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var // These are all needed for the WMI querying process
Locator: ISWbemLocator;
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
SN: string;
begin
Result := '';
try
Locator := CoSWbemLocator.Create; // Create the Location object
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
while Enum.Next(1, TempObj, Value) = S_OK do
begin
try SObject := IUnknown(TempObj) as ISWBemObject; except SObject := nil; end;
TempObj := Unassigned; // Always need to free interface in TempObj
if SObject <> nil then
begin
SProp := SObject.Properties_.Item(wmiProperty, 0);
SN := SProp.Get_Value;
if not VarIsNull(SN) then
begin
Result := SN;
Break;
end;
end;
end;
except // Trap any exceptions (Not having WMI installed will cause one!)
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CoInitializeEx(nil,COINIT_MULTITHREADED) ; //required !!! Otherwise "EOleSysError: CoInitialize has not been called" occurs (Microsoft recommends CoInitializeEx instead of CoInitialize)
CPU_PROCESSOR_COUNT := StrToInt( getWMIstring('','Win32_ComputerSystem','NumberOfProcessors') ); // number of cpu on mainboard
CPU_PHYSICAL_CORES := StrToInt( getWMIstring('','Win32_Processor','NumberOfCores') ); // number of phisical cores
CPU_LOGICAL_CORES := StrToInt( getWMIstring('','Win32_Processor','NumberOfLogicalProcessors') ); //number of logical cores
CoUninitialize; //required !!!
end;
答案 0 :(得分:1)
以下是使用GetLogicalProcessorInformation
的示例:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
type
TLogicalProcessorInformation = record
LogicalProcessorCount : integer;
NumaNodeCount : integer;
ProcessorCoreCount : integer;
ProcessorL1CacheCount : integer;
ProcessorL2CacheCount : integer;
ProcessorL3CacheCount : integer;
ProcessorPackageCount : integer;
end;
function CountSetBits(bitMask : NativeUInt) : integer;
var
lShift, i : integer;
bitTest : NativeUInt;
begin
lShift := SizeOf(NativeUInt)*8 - 1;
result := 0;
bitTest := 1 shl lShift;
for i := 0 to lShift do begin
if (bitMask and bitTest) <> 0 then Inc(result);
bitTest := bitTest shr 1;
end;
end;
function GetLogicalProcessorInfo : TLogicalProcessorInformation;
var
i: Integer;
ReturnLength: DWORD;
Buffer: array of TSystemLogicalProcessorInformation;
begin
result.LogicalProcessorCount := 0;
result.NumaNodeCount := 0;
result.ProcessorCoreCount := 0;
result.ProcessorL1CacheCount := 0;
result.ProcessorL2CacheCount := 0;
result.ProcessorL3CacheCount := 0;
result.ProcessorPackageCount := 0;
SetLength(Buffer, 256);
if not GetLogicalProcessorInformation(@Buffer[0], ReturnLength) then
begin
if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin
SetLength(Buffer,
ReturnLength div SizeOf(TSystemLogicalProcessorInformation) + 1);
if not GetLogicalProcessorInformation(@Buffer[0], ReturnLength) then
RaiseLastOSError;
end else
RaiseLastOSError;
end;
SetLength(Buffer, ReturnLength div SizeOf(TSystemLogicalProcessorInformation));
for i := 0 to High(Buffer) do begin
case Buffer[i].Relationship of
RelationNumaNode: Inc(result.NumaNodeCount);
RelationProcessorCore:
begin
Inc(result.ProcessorCoreCount);
result.LogicalProcessorCount := result.LogicalProcessorCount + CountSetBits(Buffer[i].ProcessorMask);
end;
RelationCache:
begin
if (Buffer[i].Cache.Level = 1) then Inc(result.ProcessorL1CacheCount)
else if (Buffer[i].Cache.Level = 2) then Inc(result.ProcessorL2CacheCount)
else if (Buffer[i].Cache.Level = 3) then Inc(result.ProcessorL3CacheCount);
end;
RelationProcessorPackage: Inc(result.ProcessorPackageCount);
else
raise Exception.Create('Error: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.');
end;
end;
end;
var
LProcInfo : TLogicalProcessorInformation;
begin
LProcInfo := GetLogicalProcessorInfo;
WriteLn('Logical processor count = ', LProcInfo.LogicalProcessorCount);
WriteLn('NUMA Node count = ', LProcInfo.NumaNodeCount);
WriteLn('Processor Core count = ', LProcInfo.ProcessorCoreCount);
WriteLn('L1 Cache count = ', LProcInfo.ProcessorL1CacheCount);
WriteLn('L2 Cache count = ', LProcInfo.ProcessorL2CacheCount);
WriteLn('L3 Cache count = ', LProcInfo.ProcessorL3CacheCount);
WriteLn('Package count = ', LProcInfo.ProcessorPackageCount);
ReadLn;
end.
对于XE2及更高版本,这些WinAPI定义包含在RTL中。否则,可以手动包括定义。示例实现can be found here。
例如,对于桌面i7工作站,输出:
逻辑处理器计数= 8
NUMA节点数= 1
处理器核心数= 4
L1缓存计数= 8
L2缓存计数= 4
L3缓存计数= 1
套餐数量= 1
逻辑核心数包括超线程虚拟核,处理器核心数是核的物理数,包计数返回物理CPU数,NUMA节点计数返回处理器节点数(对于大型集群计算机)。
如果您希望在较大的群集上运行,请注意以下文档:
在具有超过64个逻辑处理器的系统上,GetLogicalProcessorInformation函数检索有关当前为其分配调用线程的处理器组中的处理器的逻辑处理器信息。使用GetLogicalProcessorInformationEx函数检索有关系统上所有处理器组中处理器的信息。
答案 1 :(得分:1)
如果您对逻辑处理器的数量感兴趣-例如出于线程调度的目的,可以使用更简单,更早的 GetSystemInfo 函数:
function GetNumberOfProcessors: Integer;
var
si: TSystemInfo; //Windows.pas
begin
GetSystemInfo({var}si);
Result := si.dwNumberOfProcessors;
end;
几乎所有目的:
您想要 GetSystemInfo 提供的内容。