下面是一些 C++ 代码,它使用以下命令检测 Windows 上 L1、L2 和 L3 CPU 缓存的大小:
typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");
if (glpi)
{
DWORD bytes = 0;
glpi(0, &bytes);
size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
glpi(info.data(), &bytes);
for (size_t i = 0; i < size; i++)
{
if (info[i].Relationship == RelationCache)
{
if (info[i].Cache.Level == 1)
l1_cache_Size = info[i].Cache.Size;
if (info[i].Cache.Level == 2)
l2_cache_Size = info[i].Cache.Size;
if (info[i].Cache.Level == 3)
l3_cache_Size = info[i].Cache.Size;
}
}
}
下一步我想获取共享缓存的逻辑 CPU 核心的数量。在具有超线程的 x64 CPU 上,两个逻辑 CPU 核心通常共享 L2 缓存,所有逻辑 CPU 核心共享 L3 缓存。
读完MSDN后我认为GetLogicalProcessorInformationEx
and CACHE_关系 https://msdn.microsoft.com/en-us/library/windows/desktop/dd405483(v=vs.85).aspx and 组_亲和力 https://msdn.microsoft.com/en-us/library/windows/desktop/dd405500(v=vs.85).aspx我正在寻找的数据结构,但在尝试之后,这些数据结构似乎对我的目的毫无用处。
问题:
有没有办法使用 C/C++ 获取 Windows 上共享缓存的逻辑 CPU 核心的数量? (理想情况下不使用cpuid
直接地)
解决方案:
共享缓存的逻辑 CPU 核心数可以通过以下方式获得GetLogicalProcessorInformationEx
和CACHE_关系 https://msdn.microsoft.com/en-us/library/windows/desktop/dd405483(v=vs.85).aspx and 组_亲和力 https://msdn.microsoft.com/en-us/library/windows/desktop/dd405500(v=vs.85).aspx数据结构。这GROUP_AFFINITY.Mask
值包含为共享当前缓存的每个 CPU 核心设置的一位(RelationCache
)。以大多数具有超线程功能的 Intel CPU 为例GROUP_AFFINITY.Mask
对于具有 4 个物理 CPU 核心和 8 个逻辑 CPU 核心的 CPU,将包含为 L2 高速缓存设置的 2 位和为 L3 高速缓存设置的 8 位。
这是 C++ 代码:
#include <windows.h>
#include <vector>
#include <iostream>
using namespace std;
typedef BOOL (WINAPI *LPFN_GLPI)(LOGICAL_PROCESSOR_RELATIONSHIP,
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
int main()
{
LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformationEx");
if (!glpi)
return 1;
DWORD bytes = 0;
glpi(RelationAll, 0, &bytes);
vector<char> buffer(bytes);
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info;
if (!glpi(RelationAll, (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*) &buffer[0], &bytes))
return 1;
for (size_t i = 0; i < bytes; i += info->Size)
{
info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*) &buffer[i];
if (info->Relationship == RelationCache &&
(info->Cache.Type == CacheData ||
info->Cache.Type == CacheUnified))
{
cout << "info->Cache.Level: " << (int) info->Cache.Level << endl;
cout << "info->Cache.CacheSize: " << (int) info->Cache.CacheSize << endl;
cout << "info->Cache.GroupMask.Group: " << info->Cache.GroupMask.Group << endl;
cout << "info->Cache.GroupMask.Mask: " << info->Cache.GroupMask.Mask << endl << endl;
}
}
return 0;
}
Caveats:
我发现当在虚拟机中运行 Windows 时,上面的代码无法正确检测共享缓存的 CPU 核心数量,例如在具有 2 个虚拟 CPU 核心的 VM 上,上面的代码报告每个逻辑 CPU 核心都有一个私有 L1、L2 和 L3 缓存。