2012-12-09 3 views
3

WMI를 사용하여 CPU 캐시 정보를 얻으려고 시도했지만 정상적으로 작동하지만 레벨 2 및 레벨 3 캐시에서만 작동하므로 CPU 레벨 1 캐시 정보를 얻는 방법은 무엇입니까?CPU 레벨 1 캐시 (1 차 캐시) 정보를 얻는 방법?

+3

'GetLogicalProcessorInformation' 및'GetLogicalProcessorInformationEx'에 대한 기본 API가 있습니다. WMI는 과도한 것처럼 보입니다. –

답변

5

당신은 Win32_CacheMemory WMI 클래스를 사용할 수 있습니다,이 코드를 시도 :

{$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. 
+0

감사합니다. GetWin32_ProcessorInfo를 사용했지만 GetWin32_CacheMemory;를 다시 사용합니다. –

+1

@RRUZ Win32 API를 사용하는 접근 방식에이 솔루션을 선호 할만한 이유가 있습니까? –

+0

@RRUZ LEVEL1 만받는 방법? CacheMemoryInfo는 모든 레벨 캐시 크기를 표시합니다. 감사. –

9

가 여기에 GetLogicalProcessorInformation 기능을 사용하는 WinAPI를의 방법입니다.

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'; 

그리고 모든 레벨 1에 대한 캐시 유형, 수준과 크기를 표시하는 방법의 예 : 당신이 적어도 델파이 XE2이있는 경우 그들은 Windows 단위로 이미, 다음과 같은 정의가 필요하지 않습니다 캐시 항목 :

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; 
+0

+1 이것이 Delphi에서 올바른 방법입니다. Windows.pas는 GetLogicalProcessorInformation과 필요한 다양한 유형을 정의합니다. 적어도 XE3에서는 그렇습니다. 내가 언제 추가되었는지는 잘 모르겠다. –

+0

@David는 XE가 아니라 XE2에 있습니다. –

+0

@LURD, 정보 주셔서 감사합니다! 게시물에 포함시켜 드리겠습니다 ... – TLama

관련 문제