使用GetLogicalProcessorInformation获取逻辑处理器的详细信息(NUMA节点数、物理CPU数、CPU核心数、逻辑CPU数、各级Cache)
不过必须XP SP3以上才行。所有API大全:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363804(v=vs.85).aspx
--------------------------------------------------------------------------------
现在多核处理器已经很普及了,市场主流是双核处理器,还有4核、8核等高端产品。而且Intel推广了超线程技术(Hyper-Threading Technology, HTT),可以将一个物理核心模拟为两个逻辑处理器。这一切使得“CPU数量”这一概念变得复杂起来,对于软件开发人员来说,希望能获得物理CPU数、CPU核心数、逻辑CPU数等详细信息。
在Windows平台,可以调用GetLogicalProcessorInformation函数来获取它们的详细信息。
一、背景知识
先来明确一下名词——
physical processor packages:物理处理器封装个数,即俗称的“物理CPU数”。例如一块“Intel Core i3-2310M”只有1个“物理处理器封装个数”。若对于有多个处理器插槽的服务器,“物理处理器封装个数”很可能会大于1。
processor cores:处理器核心数,即俗称的“CPU核心数”。例如“Intel Core i3-2310M”是双核处理器,它有2个“处理器核心数”。
logical processors:逻辑处理器数,即俗称的“逻辑CPU数”。例如“Intel Core i3-2310M”支持超线程,一个物理核心能模拟为两个逻辑处理器,即一块“Intel Core i3-2310M”有4个“逻辑处理器数”。
再来看看2个大家可能不太熟悉的名词——
SMP:Symmetrical Multi-Processing,对称多处理机。
NUMA:Non Uniform Memory Access,非均匀访存模型。http://msdn.microsoft.com/en-us/library/aa363804(v=vs.85).aspx
这个两个名词牵涉到很多专业知识,这里不做详细介绍,感兴趣的同学可以自行翻阅相关资料。
老版本的Windows系统(例如Windows XP)采用的是SMP模型。但后来因多核处理器及异构计算的发展,从Windows Server 2003开始使用NUMA模型,系统中支持多个NUMA节点。对于开发人员来说,当只有1个NUMA节点时,与SMP模型是差不多的。
对于 Windows XP,在打上SP3补丁后,也可以利用GetLogicalProcessorInformation函数获得NUMA等信息。
二、GetLogicalProcessorInformation函数的使用心得
在MSDN上我们可以查到GetLogicalProcessorInformation函数的帮助——
http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx
GetLogicalProcessorInformation function
GetLogicalProcessorInformation函数还牵涉到一些结构体和枚举——
http://msdn.microsoft.com/en-us/library/ms686694(v=vs.85).aspx
SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure
http://msdn.microsoft.com/en-us/library/ms684197(v=vs.85).aspx
LOGICAL_PROCESSOR_RELATIONSHIP enumeration
http://msdn.microsoft.com/en-us/library/ms681979(v=vs.85).aspx
CACHE_DESCRIPTOR structure
http://msdn.microsoft.com/en-us/library/ms684844(v=vs.85).aspx
PROCESSOR_CACHE_TYPE enumeration
GetLogicalProcessorInformation函数用起来是有一定复杂性的。因为它返回的是SYSTEM_LOGICAL_PROCESSOR_INFORMATION数组,数组中的每一项分别描述了不同的信息,学习曲线较陡峭。
虽然MSDN上有该函数的范例代码,但是它屏蔽了很多细节,对我们的帮助有限。于是我将该范例程序作了改进,显示了SYSTEM_LOGICAL_PROCESSOR_INFORMATION数组中每一项的详细信息。
心得——
1.SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构ProcessorMask是ULONG_PTR类型的。在32位系统上是32位,64位系统上是64位。为了简化代码,建议强制转型为UINT64类型,调用printf等输出函数时使用“I64”格式码。
2.ProcessorMask是处理器掩码,每一位代表一个逻辑处理器。所以一般来说,32位系统最多支持32个逻辑处理器,64位系统最多支持64个逻辑处理器。
3.对于Windows 7和Windows Server 2008 R2来说,能突破64个逻辑处理器限制,最高支持256个逻辑处理器。新加了 处理器组(Processor Groups)概念,详见:http://msdn.microsoft.com/en-us/library/dd405503(v=vs.85).aspx。
三、全部代码
全部代码——
- #include <windows.h>
- #include <malloc.h>
- #include <stdio.h>
- #include <tchar.h>
- #if (_WIN32_WINNT < 0x0600) // [zyl910] 低版本的Windows SDK没有定义 RelationProcessorPackage 等常量
- #define RelationProcessorPackage 3
- #define RelationGroup 4
- #endif
- // [zyl910] LOGICAL_PROCESSOR_RELATIONSHIP枚举的名称
- const LPTSTR Names_LOGICAL_PROCESSOR_RELATIONSHIP[] = {
- _T("RelationProcessorCore")
- ,_T("RelationNumaNode")
- ,_T("RelationCache")
- ,_T("RelationProcessorPackage")
- ,_T("RelationGroup")
- };
- // [zyl910] PROCESSOR_CACHE_TYPE枚举的名称
- const LPTSTR Names_PROCESSOR_CACHE_TYPE[] = {
- _T("CacheUnified")
- ,_T("CacheInstruction")
- ,_T("CacheData")
- ,_T("CacheTrace")
- };
- 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 ()
- {
- LPFN_GLPI glpi;
- BOOL done = FALSE;
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = 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;
- glpi = (LPFN_GLPI) GetProcAddress(
- GetModuleHandle(TEXT("kernel32")),
- "GetLogicalProcessorInformation");
- if (NULL == glpi)
- {
- _tprintf(TEXT("\nGetLogicalProcessorInformation is not supported.\n"));
- return (1);
- }
- while (!done)
- {
- DWORD rc = glpi(buffer, &returnLength);
- if (FALSE == rc)
- {
- 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);
- }
- }
- else
- {
- done = TRUE;
- }
- }
- ptr = buffer;
- if (true) // [zyl910] 显示SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构体的详细信息
- {
- DWORD cnt = returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); // 计算SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构体的数目
- for(DWORD i=0; i<cnt; ++i)
- {
- _tprintf(TEXT("SYSTEM_LOGICAL_PROCESSOR_INFORMATION[%d]\n"), i);
- _tprintf(TEXT("\t.ProcessorMask:\t0x%.16I64X\t//%I64d\n"), (UINT64)ptr[i].ProcessorMask, (UINT64)ptr[i].ProcessorMask);
- _tprintf(TEXT("\t.Relationship:\t%d\t//%s\n"), ptr[i].Relationship, Names_LOGICAL_PROCESSOR_RELATIONSHIP[max(0,min(ptr[i].Relationship, RelationGroup))]);
- for(int j=0; j<2; ++j) _tprintf(TEXT("\t.Reserved[%d]:\t//0x%.16I64X\t%I64d\n"), j, (UINT64)ptr[i].Reserved[j], (UINT64)ptr[i].Reserved[j]);
- if (RelationCache==ptr[i].Relationship)
- {
- _tprintf(TEXT("\t.Cache.Level:\t%u\n"), ptr[i].Cache.Level);
- _tprintf(TEXT("\t.Cache.Associativity:\t0x%.2X\t//%u\n"), ptr[i].Cache.Associativity, ptr[i].Cache.Associativity);
- _tprintf(TEXT("\t.Cache.LineSize:\t0x%.4X\t//%u\n"), ptr[i].Cache.LineSize, ptr[i].Cache.LineSize);
- _tprintf(TEXT("\t.Cache.Size:\t0x%.8X\t//%u\n"), ptr[i].Cache.Size, ptr[i].Cache.Size);
- _tprintf(TEXT("\t.Cache.Type:\t%d\t//%s\n"), ptr[i].Cache.Type, Names_PROCESSOR_CACHE_TYPE[max(0,min(ptr[i].Cache.Type, CacheTrace))]);
- }
- }
- }
- while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
- {
- switch (ptr->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(ptr->ProcessorMask);
- break;
- case RelationCache:
- // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
- Cache = &ptr->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);
- ptr++;
- }
- _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);
- return 0;
- }
四、输出信息
例如我的处理器是“Intel Core i3-2310M”,该程序的输出信息为——
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[0]
- .ProcessorMask: 0x0000000000000005 //5
- .Relationship: 0 //RelationProcessorCore
- .Reserved[0]: //0x0000000000000001 1
- .Reserved[1]: //0x0000000000000000 0
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[1]
- .ProcessorMask: 0x0000000000000005 //5
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0000800000400801 140737492551681
- .Reserved[1]: //0x0000000000000002 2
- .Cache.Level: 1
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00008000 //32768
- .Cache.Type: 2 //CacheData
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[2]
- .ProcessorMask: 0x0000000000000005 //5
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0000800000400801 140737492551681
- .Reserved[1]: //0x0000000000000001 1
- .Cache.Level: 1
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00008000 //32768
- .Cache.Type: 1 //CacheInstruction
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[3]
- .ProcessorMask: 0x0000000000000005 //5
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0004000000400802 1125899911038978
- .Reserved[1]: //0x0000000000000000 0
- .Cache.Level: 2
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00040000 //262144
- .Cache.Type: 0 //CacheUnified
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[4]
- .ProcessorMask: 0x000000000000000F //15
- .Relationship: 3 //RelationProcessorPackage
- .Reserved[0]: //0x0000000000000000 0
- .Reserved[1]: //0x0000000000000000 0
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[5]
- .ProcessorMask: 0x000000000000000A //10
- .Relationship: 0 //RelationProcessorCore
- .Reserved[0]: //0x0000000000000001 1
- .Reserved[1]: //0x0000000000000000 0
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[6]
- .ProcessorMask: 0x000000000000000A //10
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0000800000400801 140737492551681
- .Reserved[1]: //0x0000000000000002 2
- .Cache.Level: 1
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00008000 //32768
- .Cache.Type: 2 //CacheData
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[7]
- .ProcessorMask: 0x000000000000000A //10
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0000800000400801 140737492551681
- .Reserved[1]: //0x0000000000000001 1
- .Cache.Level: 1
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00008000 //32768
- .Cache.Type: 1 //CacheInstruction
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[8]
- .ProcessorMask: 0x000000000000000A //10
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0004000000400802 1125899911038978
- .Reserved[1]: //0x0000000000000000 0
- .Cache.Level: 2
- .Cache.Associativity: 0x08 //8
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00040000 //262144
- .Cache.Type: 0 //CacheUnified
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[9]
- .ProcessorMask: 0x000000000000000F //15
- .Relationship: 2 //RelationCache
- .Reserved[0]: //0x0030000000400C03 13510798886308867
- .Reserved[1]: //0x0000000000000000 0
- .Cache.Level: 3
- .Cache.Associativity: 0x0C //12
- .Cache.LineSize: 0x0040 //64
- .Cache.Size: 0x00300000 //3145728
- .Cache.Type: 0 //CacheUnified
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION[10]
- .ProcessorMask: 0x000000000000000F //15
- .Relationship: 1 //RelationNumaNode
- .Reserved[0]: //0x0000000000000000 0
- .Reserved[1]: //0x0000000000000000 0
- GetLogicalProcessorInformation results:
- Number of NUMA nodes: 1
- Number of physical processor packages: 1
- Number of processor cores: 2
- Number of logical processors: 4
- Number of processor L1/L2/L3 caches: 4/2/1
使用GetLogicalProcessorInformation获取逻辑处理器的详细信息(NUMA节点数、物理CPU数、CPU核心数、逻辑CPU数、各级Cache)的更多相关文章
- php反射机制获取未知类的详细信息
使用ReflectionClass就可以获取未知类的详细信息 demo: require("hello.php"); $class = new ReflectionClass(&q ...
- android笔记---百度地图api应用 (二) 获取公交路线的详细信息
package com.example.bdtest; import com.baidu.mapapi.MKEvent; import com.baidu.mapapi.MKPlanNode; imp ...
- PHP怎么获取系统信息和服务器详细信息
https://zhidao.baidu.com/question/1435990326608475859.html 获取系统类型及版本号: php_uname() (例:Windows NT COM ...
- 微信小程序开发(十一)获取手机的完整详细信息
// succ.wxml <view style='position:absolute; top:30%; left:35%;font-size:36rpx'>{{name}}:签到成功. ...
- zTree获取当前节点的下一级子节点数
使用zTree插件实现树形图中,需要获取当前点击的父节点的子节点数的需求,使用treeNode.children获取子节点数据集合,使用length方法获取集合长度.将当前节点的treeNode传入即 ...
- 【Android Developers Training】 99. 获取联系人详细信息
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 01.阿里云SDK调用,获取ESC主机详细信息
一:通过python SDK获取云主机的详细信息 1.创建Accessky码(不做展示) 2.通过pip安装SDK模块,这个阿里云帮助里面有,也不做详细展示. 3.详细使用方法看代码 我下面展示的返回 ...
- PHP获取当前服务器详细信息
最近正在用PHP写一个企业级的CMS,后台需要用到PHP获取当前服务器的详细信息以及相关系统参数信息,整理了整理,现在贴这儿,以备后用. 获取系统类型及版本号: php_uname() (例:W ...
- 查看LINUX 系统硬件等详细信息
转载这位朋友[地址] 几个cpu more /proc/cpuinfo |grep "physical id"|uniq|wc -l 每个cpu是几核(假设cpu配置相同) mor ...
随机推荐
- 批量更新数据小心SQL触发器的陷阱
批量更新数据时候,Inserted和Deleted临时表也是批量的,但触发器只会调用执行一次!两个概念千万不要弄混淆! 错误的理解:例如:创建在A表上创建了一个Update触发器,里面写的是Updat ...
- PHP安全编程:会话数据注入 比会话劫持更强大的攻击(转)
一个与会话暴露类似的问题是会话注入.此类攻击是基于你的WEB服务器除了对会话存储目录有读取权限外,还有写入权限.因此,存在着编写一段允许其他用户添加,编辑或删除会话的脚本的可能.下例显示了一个允许用户 ...
- CreateProcess函数具体解释
CreateProcess说明:WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程执行指定的可执行文件. 函数原型:BOOL CreateProcess( ...
- Exception in thread "main" brut.androlib.err.UndefinedResObject: resource spec: 0x01030200(转)
反编译时遇到标题中的异常,根据描述,原因是找不到资源文件,最有可能的原因是apk中使用了系统资源. 解决办法如下: 从手机中导出framework-res.apk文件,该文件在/system/fram ...
- Android(java)学习笔记242:多媒体之设置全屏的方法
在实际的应用程序开发中,我们有时需要把 Activity 设置成全屏显示,一般情况下,可以通过两种方式来设置全屏显示效果.其一,通过在代码中可以设置,其二,通过manifest配置文件来设置全屏. 其 ...
- NYOJ2括号配对问题
括号配对是最基本的栈的问题,它是栈入门的经典题目,思路是,如果是左括号直接进栈,如果是右括号,这时就要比较栈顶的元素与他是否匹配,如果匹配则出栈,否则进栈,下面是代码的实现: #include < ...
- 请输出in.txt文件中的2 4 6 8 9 10 12行
in.txt文件: 学号 姓名 性别 年龄 1001 张三 男 18 1002 赵四 男 19 1003 李丽 女 18 1004 刘芳 女 32 1005 王五 男 54 1006 小明 男 32 ...
- eclipse开发servlet应用,Tomcat无法访问jpg图片 ===第二版===
之前版本中,设置完后,确实可以访问图片了,但是问题接着来了,那就是,无法访问servlet的服务了. 后来想了下,原因也挺好理解的,设置到了Tomcat目录,而项目没有部署,所以没能访问. 但是怎么两 ...
- SVN global ignore pattern for c#
*.resharperoptions Web_Data log */[Bb]in [Bb]in */obj obj */TestResults TestResults *.svclog Debug ...
- 多核CPU利用测试
一直在想程序上是否特意让线程在指定的CPU上去运行,这样可以提高运行效率,所以特地写个代码让CPU使用率画正弦曲线的实验,我使用的是AMD X4 641的CPU,为四核四线程的片子. 代码如下 # ...