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)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)