问题
I've tried to get CPU cache information by using WMI and it works great, but only for Level 2 and Level 3 cache, so my question is, how to get CPU Level 1 cache information ?
回答1:
You can use the Win32_CacheMemory WMI class, try this code:
{$APPTYPE CONSOLE}
uses
SysUtils,
ActiveX,
ComObj,
Variants;
procedure GetWin32_CacheMemoryInfo;
const
WbemUser ='';
WbemPassword ='';
WbemComputer ='localhost';
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT MaxCacheSize, Purpose FROM Win32_CacheMemory','WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
Writeln(Format('MaxCacheSize %d',[Integer(FWbemObject.MaxCacheSize)]));
Writeln(Format('Purpose %s',[String(FWbemObject.Purpose)]));
FWbemObject:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
GetWin32_CacheMemoryInfo;
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
回答2:
Here's the WinAPI way, which uses the GetLogicalProcessorInformation function. If you have at least Delphi XE2, you won't need the following definitions, they are already in the Windows
unit:
type
TLogicalProcessorRelationship = (
RelationProcessorCore = 0,
RelationNumaNode = 1,
RelationCache = 2,
RelationProcessorPackage = 3,
RelationGroup = 4,
RelationAll = $FFFF
);
TProcessorCacheType = (
CacheUnified,
CacheInstruction,
CacheData,
CacheTrace
);
TCacheDescriptor = record
Level: Byte;
Associativity: Byte;
LineSize: Word;
Size: DWORD;
pcType: TProcessorCacheType;
end;
PSystemLogicalProcessorInformation = ^TSystemLogicalProcessorInformation;
TSystemLogicalProcessorInformation = record
ProcessorMask: ULONG_PTR;
Relationship: TLogicalProcessorRelationship;
case Integer of
0: (Flags: Byte);
1: (NodeNumber: DWORD);
2: (Cache: TCacheDescriptor);
3: (Reserved: array [0..1] of ULONGLONG);
end;
function GetLogicalProcessorInformation(
Buffer: PSystemLogicalProcessorInformation;
var ReturnLength: DWORD): BOOL; stdcall;
external kernel32 name 'GetLogicalProcessorInformation';
And the example of how to show the cache type, level and size for all level 1 cache entries:
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
I: Integer;
ReturnLength: DWORD;
Buffer: array of TSystemLogicalProcessorInformation;
begin
SetLength(Buffer, 1);
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;
for I := 0 to High(Buffer) do
begin
if (Buffer[I].Relationship = RelationCache) and
(Buffer[I].Cache.Level = 1) then
begin
S := 'Type: ';
case Buffer[I].Cache.pcType of
CacheUnified: S := S + 'Unified cache';
CacheInstruction: S := S + 'Instruction cache';
CacheData: S := S + 'Data cache';
CacheTrace: S := S + 'Trace cache';
end;
S := S + sLineBreak;
S := S + 'Level: ' + IntToStr(Buffer[I].Cache.Level) + sLineBreak;
S := S + 'Size: ' + IntToStr(Buffer[I].Cache.Size) + ' B';
ShowMessage(S);
end;
end;
end;
来源:https://stackoverflow.com/questions/13788715/how-to-get-cpu-level-1-cache-primary-cache-information