Skip to content

Commit

Permalink
Implement support for capturing CPU information.
Browse files Browse the repository at this point in the history
Capture information about cores and caches, and include it in the .csv
output files.
  • Loading branch information
tpn committed Dec 7, 2022
1 parent 716a0dc commit 5ca1248
Show file tree
Hide file tree
Showing 6 changed files with 456 additions and 8 deletions.
49 changes: 49 additions & 0 deletions src/PerfectHash/BulkCreateBestCsv.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,55 @@ Module Name:
&Context->Rtl->CpuFeatures.Brand, \
OUTPUT_STRING) \
\
ENTRY(CpuSocketCount, \
Context->Rtl->CpuFeatures.ProcessorPackageCount, \
OUTPUT_INT) \
\
ENTRY(CpuNumaNodeCount, \
Context->Rtl->CpuFeatures.NumaNodeCount, \
OUTPUT_INT) \
\
ENTRY(CpuProcessorCoreCount, \
Context->Rtl->CpuFeatures.ProcessorCoreCount, \
OUTPUT_INT) \
\
ENTRY(CpuLogicalProcessorCount, \
Context->Rtl->CpuFeatures.LogicalProcessorCount, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1InstructionSize, \
Context->Rtl->CpuFeatures.Caches.L1.Instruction.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1DataSize, \
Context->Rtl->CpuFeatures.Caches.L1.Data.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1Total, \
((ULONGLONG)Context->Rtl->CpuFeatures.Caches.L1.Instruction.Size + \
(ULONGLONG)Context->Rtl->CpuFeatures.Caches.L1.Data.Size), \
OUTPUT_INT) \
\
ENTRY(CpuCacheL2UnifiedSize, \
Context->Rtl->CpuFeatures.Caches.L2.Unified.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL3UnifiedSize, \
Context->Rtl->CpuFeatures.Caches.L3.Unified.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1TraceSize, \
Context->Rtl->CpuFeatures.Caches.L1.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL2TraceSize, \
Context->Rtl->CpuFeatures.Caches.L2.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL3TraceSize, \
Context->Rtl->CpuFeatures.Caches.L3.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(KeysName, \
&Keys->File->Path->BaseNameA, \
OUTPUT_STRING) \
Expand Down
57 changes: 57 additions & 0 deletions src/PerfectHash/BulkCreateCsv.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,63 @@ Module Name:
&Context->HexHeaderHash, \
OUTPUT_STRING) \
\
ENTRY(ComputerName, \
&Context->ComputerName, \
OUTPUT_STRING) \
\
ENTRY(CpuBrand, \
&Context->Rtl->CpuFeatures.Brand, \
OUTPUT_STRING) \
\
ENTRY(CpuSocketCount, \
Context->Rtl->CpuFeatures.ProcessorPackageCount, \
OUTPUT_INT) \
\
ENTRY(CpuNumaNodeCount, \
Context->Rtl->CpuFeatures.NumaNodeCount, \
OUTPUT_INT) \
\
ENTRY(CpuProcessorCoreCount, \
Context->Rtl->CpuFeatures.ProcessorCoreCount, \
OUTPUT_INT) \
\
ENTRY(CpuLogicalProcessorCount, \
Context->Rtl->CpuFeatures.LogicalProcessorCount, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1InstructionSize, \
Context->Rtl->CpuFeatures.Caches.L1.Instruction.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1DataSize, \
Context->Rtl->CpuFeatures.Caches.L1.Data.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1Total, \
((ULONGLONG)Context->Rtl->CpuFeatures.Caches.L1.Instruction.Size + \
(ULONGLONG)Context->Rtl->CpuFeatures.Caches.L1.Data.Size), \
OUTPUT_INT) \
\
ENTRY(CpuCacheL2UnifiedSize, \
Context->Rtl->CpuFeatures.Caches.L2.Unified.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL3UnifiedSize, \
Context->Rtl->CpuFeatures.Caches.L3.Unified.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL1TraceSize, \
Context->Rtl->CpuFeatures.Caches.L1.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL2TraceSize, \
Context->Rtl->CpuFeatures.Caches.L2.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(CpuCacheL3TraceSize, \
Context->Rtl->CpuFeatures.Caches.L3.Trace.Size, \
OUTPUT_INT) \
\
ENTRY(KeysName, \
&Keys->File->Path->BaseNameA, \
OUTPUT_STRING) \
Expand Down
15 changes: 15 additions & 0 deletions src/PerfectHash/PerfectHash.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,19 @@
</Expand>
</Type>

<Type Name="_SYSTEM_LOGICAL_PROCESSOR_INFO_ARRAY">
<Expand>
<Item Name="&lt;Count&gt;">Count</Item>
<Item Name="&lt;Size In Bytes&gt;">Size In Bytes</Item>
<Synthetic Name="&lt;ProcessorInfo&gt;">
<Expand>
<ArrayItems>
<Size>Count</Size>
<ValuePointer Condition="Count &gt; 0 &amp;&amp; ProcInfo != nullptr">ProcInfo</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
</Expand>
</Type>

</AutoVisualizer>
199 changes: 192 additions & 7 deletions src/PerfectHash/Rtl.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,6 @@ RtlInitialize(
goto Error;
}

Result = RtlInitializeBitManipulationFunctionPointers(Rtl);
if (FAILED(Result)) {
PH_ERROR(RtlInitializeBitManipulationFunctionPointers, Result);
goto Error;
}

Result = RtlInitializeLargePages(Rtl);
if (FAILED(Result)) {
PH_ERROR(RtlInitializeLargePages, Result);
Expand Down Expand Up @@ -285,6 +279,7 @@ RtlRundown(
{
ULONG Index;
HMODULE *Module;
PVOID Buffer;

if (!ARGUMENT_PRESENT(Rtl)) {
return;
Expand All @@ -297,6 +292,14 @@ RtlRundown(
Rtl->CryptProv = 0;
}

Buffer = Rtl->CpuFeatures.ProcInfoArray.ProcInfo;
if (Buffer != NULL) {
if (!VirtualFree(Buffer, 0, MEM_RELEASE)) {
SYS_ERROR(VirtualFree);
}
Rtl->CpuFeatures.ProcInfoArray.ProcInfo = NULL;
}

//
// Free any loaded modules.
//
Expand Down Expand Up @@ -447,6 +450,165 @@ Return Value:


#if defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86)
HRESULT
RtlInitializeCpuFeaturesLogicalProcessors(
_In_ PRTL Rtl
)
/*++
Routine Description:
This routine initializes the logical processor information of the CPU
features structure in the provided Rtl instance.
Arguments:
Rtl - Supplies a pointer to an RTL instance.
Return Value:
S_OK - Success.
PH_E_SYSTEM_CALL_FAILED - System call failed.
--*/
{
SIZE_T Index;
BOOL Success;
HRESULT Result;
DWORD LastError;
PVOID ProcInfoBuffer;
DWORD ProcInfoLength;
ULONG ProcessorMaskBits;
PCPU_CACHES Caches;
PCPU_CACHE_LEVEL CacheLevel;
PCACHE_DESCRIPTOR Cache;
PCACHE_DESCRIPTOR CacheDesc;
PRTL_CPU_FEATURES Features;
PSYSTEM_LOGICAL_PROCESSOR_INFO_ARRAY ProcInfoArray;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ProcInfo;

Features = &Rtl->CpuFeatures;

//
// Obtain the processor info.
//

ProcInfoLength = 0;
Success = GetLogicalProcessorInformation(NULL, &ProcInfoLength);
if (Success) {
PH_RAISE(PH_E_INVARIANT_CHECK_FAILED);
} else {
LastError = GetLastError();
if (LastError != ERROR_INSUFFICIENT_BUFFER) {
SYS_ERROR(GetLogicalProcessorInformation);
Result = PH_E_SYSTEM_CALL_FAILED;
goto End;
}
}

ProcInfoBuffer = VirtualAlloc(NULL,
ProcInfoLength,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);

if (!ProcInfoBuffer) {
Result = E_OUTOFMEMORY;
goto End;
}

Success = GetLogicalProcessorInformation(ProcInfoBuffer, &ProcInfoLength);
if (!Success) {
SYS_ERROR(GetLogicalProcessorInformation);
Result = PH_E_SYSTEM_CALL_FAILED;
goto End;
}

ProcInfoArray = &Features->ProcInfoArray;
ProcInfoArray->Count = ProcInfoLength / sizeof(*ProcInfo);
ProcInfoArray->SizeInBytes = ProcInfoLength;

ProcInfoArray->ProcInfo = (
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)ProcInfoBuffer
);

Caches = &Features->Caches;

for (Index = 0; Index < ProcInfoArray->Count; Index++) {

ProcInfo = &ProcInfoArray->ProcInfo[Index];

switch (ProcInfo->Relationship) {
case RelationNumaNode:
Features->NumaNodeCount++;
break;

case RelationProcessorCore:
Features->ProcessorCoreCount++;

ProcessorMaskBits = (ULONG)(
Rtl->PopulationCountPointer(ProcInfo->ProcessorMask)
);
Features->LogicalProcessorCount += ProcessorMaskBits;
break;

case RelationProcessorPackage:
Features->ProcessorPackageCount++;
break;

case RelationCache:
CacheDesc = &ProcInfo->Cache;

if (CacheDesc->Level > 4) {
break;
}

Caches->NumberOfLevels = max(Caches->NumberOfLevels,
CacheDesc->Level);

CacheLevel = &Caches->Level[CacheDesc->Level-1];
Cache = &CacheLevel->AsArray[CacheDesc->Type];
if (Cache->Level == 0) {
CopyMemoryInline(Cache, CacheDesc, sizeof(*Cache));
} else {
Cache->Size += CacheDesc->Size;
}
break;

case RelationAll:
break;

case RelationGroup:
break;

case RelationNumaNodeEx:
break;

case RelationProcessorDie:
break;

case RelationProcessorModule:
break;

default:
break;
}

}

Features->Flags.HasProcessorInformation = TRUE;
Result = S_OK;

//
// Intentional follow-on.
//

End:

return Result;
}


_Use_decl_annotations_
HRESULT
RtlInitializeCpuFeatures(
Expand All @@ -467,6 +629,8 @@ Return Value:
S_OK - Success.
PH_E_SYSTEM_CALL_FAILED - System call failed.
--*/
{
HRESULT Result;
Expand Down Expand Up @@ -602,7 +766,28 @@ Return Value:

}

Result = S_OK;
//
// Initialize the bit manipulation features next, then the processor info
// (which needs PopulationCount).
//

Result = RtlInitializeBitManipulationFunctionPointers(Rtl);
if (FAILED(Result)) {
PH_ERROR(RtlInitializeBitManipulationFunctionPointers, Result);
goto End;
}

Result = RtlInitializeCpuFeaturesLogicalProcessors(Rtl);
if (FAILED(Result)) {
PH_ERROR(RtlInitializeCpuFeaturesLogicalProcessors, Result);
goto End;
}

//
// Intentional follow-on.
//

End:

return Result;
}
Expand Down
Loading

0 comments on commit 5ca1248

Please sign in to comment.