How to get CPU Level 1 cache (primary cache) information?

允我心安 提交于 2020-01-23 10:51:26

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!