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

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

概述下面是一些使用 GetLogicalProcessorInformation在Windows上检测L1,L2和L3 CPU缓存大小的C代码: typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress( 下面是一些使用 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: 1info->Cache.CacheSize: 32768info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 1info->Cache.Level: 1info->Cache.CacheSize: 32768info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 1info->Cache.Level: 2info->Cache.CacheSize: 262144info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 1info->Cache.Level: 3info->Cache.CacheSize: 31457280info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 1info->Cache.Level: 1info->Cache.CacheSize: 32768info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 2info->Cache.Level: 1info->Cache.CacheSize: 32768info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 2info->Cache.Level: 2info->Cache.CacheSize: 262144info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 2info->Cache.Level: 3info->Cache.CacheSize: 31457280info->Cache.GroupMask.Group: 0info->Cache.GroupMask.Mask: 2

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

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

总结

以上是内存溢出为你收集整理的c – 获取共享缓存的逻辑CPU核心数(L1,L2,L3)全部内容,希望文章能够帮你解决c – 获取共享缓存的逻辑CPU核心数(L1,L2,L3)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1225103.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存