加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 获取共享缓存的逻辑CPU核心数(L1,L2,L3)

发布时间:2020-12-16 06:53:54 所属栏目:百科 来源:网络整理
导读:下面是一些使用 GetLogicalProcessorInformation在Windows上检测L1,L2和L3 CPU缓存大小的C代码: typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,PDWORD);LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress( GetModuleHandle(TEXT("ke
下面是一些使用 GetLogicalProcessorInformation在Windows上检测L1,L2和L3 CPU缓存大小的C代码:

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和CACHE_RELATIONSHIP和GROUP_AFFINITY我在寻找数据结构,但在尝试了这些数据结构之后,对我来说似乎毫无用处.

题:

有没有办法让使用C/C++在Windows上共享缓存的逻辑CPU核心数量? (理想情况下不直接使用cpuid)

解:

可以使用GetLogicalProcessorInformationEx和CACHE_RELATIONSHIP和GROUP_AFFINITY数据结构获得共享高速缓存的逻辑CPU核心数. GROUP_AFFINITY.Mask值包含为共享当前缓存(RelationCache)的每个CPU核心设置的一个位.作为大多数具有超线程的Intel CPU的示例,GROUP_AFFINITY.Mask将包含为L2缓存设置的2位和为具有4个物理CPU核心和8个逻辑CPU核心的CPU设置的用于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,&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;
}

注意事项:

我发现在虚拟机内运行Windows时,上面的代码无法正确检测共享缓存的CPU核心数量,例如:在具有2个虚拟CPU核心的VM上,上面的代码报告每个逻辑CPU核心具有专用的L1,L2和L3缓存.

解决方法

@RbMm: but CACHE_RELATIONSHIP contains all info needed. number of logical CPU cores = number of bits set in Cache->GroupMask.Mask

我已经在AppVeyor CI上测试了这个(甚至在发布到stackoverflow之前).这是x64 CPU的输出:

info->Cache.Level: 1
info->Cache.CacheSize: 32768
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 1

info->Cache.Level: 1
info->Cache.CacheSize: 32768
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 1

info->Cache.Level: 2
info->Cache.CacheSize: 262144
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 1

info->Cache.Level: 3
info->Cache.CacheSize: 31457280
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 1

info->Cache.Level: 1
info->Cache.CacheSize: 32768
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 2

info->Cache.Level: 1
info->Cache.CacheSize: 32768
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 2

info->Cache.Level: 2
info->Cache.CacheSize: 262144
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 2

info->Cache.Level: 3
info->Cache.CacheSize: 31457280
info->Cache.GroupMask.Group: 0
info->Cache.GroupMask.Mask: 2

根据MSDN文档:“GroupMask.Mask – 指定指定组内零个或多个处理器的亲和性的位图.”基于此文档,我期待L3缓存的不同GroupMask.Mask,但上面的输出不显示这一点.对我来说,GroupMask.Mask中的数据毫无意义!

这是一个产生上述数据的link to the code

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读