Last active
August 29, 2015 14:10
-
-
Save DiKorsch/df6bc5953babc6fd3a7a to your computer and use it in GitHub Desktop.
windows NUMA API example from a presentation for a NUMA Seminar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* origin: http://technet.microsoft.com/de-de/ms683194%28v=vs.80%29 */ | |
#include <windows.h> | |
#include <malloc.h> | |
#include <stdio.h> | |
#include <tchar.h> | |
typedef BOOL (WINAPI *LPFN_GLPI)( | |
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, | |
PDWORD); | |
// Helper function to count set bits in the processor mask. | |
DWORD CountSetBits(ULONG_PTR bitMask) | |
{ | |
DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1; | |
DWORD bitSetCount = 0; | |
ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; | |
DWORD i; | |
for (i = 0; i <= LSHIFT; ++i) | |
{ | |
bitSetCount += ((bitMask & bitTest)?1:0); | |
bitTest/=2; | |
} | |
return bitSetCount; | |
} | |
int _cdecl _tmain () | |
{ | |
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; | |
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer_begin = NULL; | |
DWORD returnLength = 0; | |
DWORD logicalProcessorCount = 0; | |
DWORD numaNodeCount = 0; | |
DWORD processorCoreCount = 0; | |
DWORD processorL1CacheCount = 0; | |
DWORD processorL2CacheCount = 0; | |
DWORD processorL3CacheCount = 0; | |
DWORD processorPackageCount = 0; | |
DWORD byteOffset = 0; | |
PCACHE_DESCRIPTOR Cache; | |
while (GetLogicalProcessorInformation(buffer, &returnLength) == FALSE) | |
{ | |
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) | |
{ | |
if (buffer) | |
free(buffer); | |
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc(returnLength); | |
if (NULL == buffer) | |
{ | |
_tprintf(TEXT("\nError: Allocation failure\n")); | |
return (2); | |
} | |
} | |
else | |
{ | |
_tprintf(TEXT("\nError %d\n"), GetLastError()); | |
return (3); | |
} | |
} | |
buffer_begin = buffer; | |
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) | |
{ | |
switch (buffer->Relationship) | |
{ | |
case RelationNumaNode: | |
// Non-NUMA systems report a single record of this type. | |
numaNodeCount++; | |
break; | |
case RelationProcessorCore: | |
processorCoreCount++; | |
// A hyperthreaded core supplies more than one logical processor. | |
logicalProcessorCount += CountSetBits(buffer->ProcessorMask); | |
break; | |
case RelationCache: | |
// Cache data is in buffer->Cache, one CACHE_DESCRIPTOR structure for each cache. | |
Cache = &buffer->Cache; | |
if (Cache->Level == 1) | |
{ | |
processorL1CacheCount++; | |
} | |
else if (Cache->Level == 2) | |
{ | |
processorL2CacheCount++; | |
} | |
else if (Cache->Level == 3) | |
{ | |
processorL3CacheCount++; | |
} | |
break; | |
case RelationProcessorPackage: | |
// Logical processors share a physical package. | |
processorPackageCount++; | |
break; | |
default: | |
_tprintf(TEXT("\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\n")); | |
break; | |
} | |
byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); | |
buffer++; | |
} | |
_tprintf(TEXT("\nGetLogicalProcessorInformation results:\n")); | |
_tprintf(TEXT("Number of NUMA nodes: %d\n"), | |
numaNodeCount); | |
_tprintf(TEXT("Number of physical processor packages: %d\n"), | |
processorPackageCount); | |
_tprintf(TEXT("Number of processor cores: %d\n"), | |
processorCoreCount); | |
_tprintf(TEXT("Number of logical processors: %d\n"), | |
logicalProcessorCount); | |
_tprintf(TEXT("Number of processor L1/L2/L3 caches: %d/%d/%d\n"), | |
processorL1CacheCount, | |
processorL2CacheCount, | |
processorL3CacheCount); | |
free(buffer_begin); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment