不过必须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

三、全部代码

  全部代码——

  1. #include <windows.h>
  2. #include <malloc.h>
  3. #include <stdio.h>
  4. #include <tchar.h>
  5. #if (_WIN32_WINNT < 0x0600)  // [zyl910] 低版本的Windows SDK没有定义 RelationProcessorPackage 等常量
  6. #define RelationProcessorPackage    3
  7. #define RelationGroup   4
  8. #endif
  9. // [zyl910] LOGICAL_PROCESSOR_RELATIONSHIP枚举的名称
  10. const LPTSTR Names_LOGICAL_PROCESSOR_RELATIONSHIP[] = {
  11. _T("RelationProcessorCore")
  12. ,_T("RelationNumaNode")
  13. ,_T("RelationCache")
  14. ,_T("RelationProcessorPackage")
  15. ,_T("RelationGroup")
  16. };
  17. // [zyl910] PROCESSOR_CACHE_TYPE枚举的名称
  18. const LPTSTR Names_PROCESSOR_CACHE_TYPE[] = {
  19. _T("CacheUnified")
  20. ,_T("CacheInstruction")
  21. ,_T("CacheData")
  22. ,_T("CacheTrace")
  23. };
  24. typedef BOOL (WINAPI *LPFN_GLPI)(
  25. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
  26. PDWORD);
  27. // Helper function to count set bits in the processor mask.
  28. DWORD CountSetBits(ULONG_PTR bitMask)
  29. {
  30. DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
  31. DWORD bitSetCount = 0;
  32. ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
  33. DWORD i;
  34. for (i = 0; i <= LSHIFT; ++i)
  35. {
  36. bitSetCount += ((bitMask & bitTest)?1:0);
  37. bitTest/=2;
  38. }
  39. return bitSetCount;
  40. }
  41. int _cdecl _tmain ()
  42. {
  43. LPFN_GLPI glpi;
  44. BOOL done = FALSE;
  45. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
  46. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
  47. DWORD returnLength = 0;
  48. DWORD logicalProcessorCount = 0;
  49. DWORD numaNodeCount = 0;
  50. DWORD processorCoreCount = 0;
  51. DWORD processorL1CacheCount = 0;
  52. DWORD processorL2CacheCount = 0;
  53. DWORD processorL3CacheCount = 0;
  54. DWORD processorPackageCount = 0;
  55. DWORD byteOffset = 0;
  56. PCACHE_DESCRIPTOR Cache;
  57. glpi = (LPFN_GLPI) GetProcAddress(
  58. GetModuleHandle(TEXT("kernel32")),
  59. "GetLogicalProcessorInformation");
  60. if (NULL == glpi)
  61. {
  62. _tprintf(TEXT("\nGetLogicalProcessorInformation is not supported.\n"));
  63. return (1);
  64. }
  65. while (!done)
  66. {
  67. DWORD rc = glpi(buffer, &returnLength);
  68. if (FALSE == rc)
  69. {
  70. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  71. {
  72. if (buffer)
  73. free(buffer);
  74. buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(
  75. returnLength);
  76. if (NULL == buffer)
  77. {
  78. _tprintf(TEXT("\nError: Allocation failure\n"));
  79. return (2);
  80. }
  81. }
  82. else
  83. {
  84. _tprintf(TEXT("\nError %d\n"), GetLastError());
  85. return (3);
  86. }
  87. }
  88. else
  89. {
  90. done = TRUE;
  91. }
  92. }
  93. ptr = buffer;
  94. if (true)   // [zyl910] 显示SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构体的详细信息
  95. {
  96. DWORD cnt = returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);    // 计算SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构体的数目
  97. for(DWORD i=0; i<cnt; ++i)
  98. {
  99. _tprintf(TEXT("SYSTEM_LOGICAL_PROCESSOR_INFORMATION[%d]\n"), i);
  100. _tprintf(TEXT("\t.ProcessorMask:\t0x%.16I64X\t//%I64d\n"), (UINT64)ptr[i].ProcessorMask, (UINT64)ptr[i].ProcessorMask);
  101. _tprintf(TEXT("\t.Relationship:\t%d\t//%s\n"), ptr[i].Relationship, Names_LOGICAL_PROCESSOR_RELATIONSHIP[max(0,min(ptr[i].Relationship, RelationGroup))]);
  102. 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]);
  103. if (RelationCache==ptr[i].Relationship)
  104. {
  105. _tprintf(TEXT("\t.Cache.Level:\t%u\n"), ptr[i].Cache.Level);
  106. _tprintf(TEXT("\t.Cache.Associativity:\t0x%.2X\t//%u\n"), ptr[i].Cache.Associativity, ptr[i].Cache.Associativity);
  107. _tprintf(TEXT("\t.Cache.LineSize:\t0x%.4X\t//%u\n"), ptr[i].Cache.LineSize, ptr[i].Cache.LineSize);
  108. _tprintf(TEXT("\t.Cache.Size:\t0x%.8X\t//%u\n"), ptr[i].Cache.Size, ptr[i].Cache.Size);
  109. _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))]);
  110. }
  111. }
  112. }
  113. while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
  114. {
  115. switch (ptr->Relationship)
  116. {
  117. case RelationNumaNode:
  118. // Non-NUMA systems report a single record of this type.
  119. numaNodeCount++;
  120. break;
  121. case RelationProcessorCore:
  122. processorCoreCount++;
  123. // A hyperthreaded core supplies more than one logical processor.
  124. logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
  125. break;
  126. case RelationCache:
  127. // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
  128. Cache = &ptr->Cache;
  129. if (Cache->Level == 1)
  130. {
  131. processorL1CacheCount++;
  132. }
  133. else if (Cache->Level == 2)
  134. {
  135. processorL2CacheCount++;
  136. }
  137. else if (Cache->Level == 3)
  138. {
  139. processorL3CacheCount++;
  140. }
  141. break;
  142. case RelationProcessorPackage:
  143. // Logical processors share a physical package.
  144. processorPackageCount++;
  145. break;
  146. default:
  147. _tprintf(TEXT("\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\n"));
  148. break;
  149. }
  150. byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
  151. ptr++;
  152. }
  153. _tprintf(TEXT("\nGetLogicalProcessorInformation results:\n"));
  154. _tprintf(TEXT("Number of NUMA nodes: %d\n"),
  155. numaNodeCount);
  156. _tprintf(TEXT("Number of physical processor packages: %d\n"),
  157. processorPackageCount);
  158. _tprintf(TEXT("Number of processor cores: %d\n"),
  159. processorCoreCount);
  160. _tprintf(TEXT("Number of logical processors: %d\n"),
  161. logicalProcessorCount);
  162. _tprintf(TEXT("Number of processor L1/L2/L3 caches: %d/%d/%d\n"),
  163. processorL1CacheCount,
  164. processorL2CacheCount,
  165. processorL3CacheCount);
  166. free(buffer);
  167. return 0;
  168. }

四、输出信息

  例如我的处理器是“Intel Core i3-2310M”,该程序的输出信息为——

  1. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[0]
  2. .ProcessorMask: 0x0000000000000005  //5
  3. .Relationship:  0   //RelationProcessorCore
  4. .Reserved[0]:   //0x0000000000000001    1
  5. .Reserved[1]:   //0x0000000000000000    0
  6. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[1]
  7. .ProcessorMask: 0x0000000000000005  //5
  8. .Relationship:  2   //RelationCache
  9. .Reserved[0]:   //0x0000800000400801    140737492551681
  10. .Reserved[1]:   //0x0000000000000002    2
  11. .Cache.Level:   1
  12. .Cache.Associativity:   0x08    //8
  13. .Cache.LineSize:    0x0040  //64
  14. .Cache.Size:    0x00008000  //32768
  15. .Cache.Type:    2   //CacheData
  16. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[2]
  17. .ProcessorMask: 0x0000000000000005  //5
  18. .Relationship:  2   //RelationCache
  19. .Reserved[0]:   //0x0000800000400801    140737492551681
  20. .Reserved[1]:   //0x0000000000000001    1
  21. .Cache.Level:   1
  22. .Cache.Associativity:   0x08    //8
  23. .Cache.LineSize:    0x0040  //64
  24. .Cache.Size:    0x00008000  //32768
  25. .Cache.Type:    1   //CacheInstruction
  26. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[3]
  27. .ProcessorMask: 0x0000000000000005  //5
  28. .Relationship:  2   //RelationCache
  29. .Reserved[0]:   //0x0004000000400802    1125899911038978
  30. .Reserved[1]:   //0x0000000000000000    0
  31. .Cache.Level:   2
  32. .Cache.Associativity:   0x08    //8
  33. .Cache.LineSize:    0x0040  //64
  34. .Cache.Size:    0x00040000  //262144
  35. .Cache.Type:    0   //CacheUnified
  36. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[4]
  37. .ProcessorMask: 0x000000000000000F  //15
  38. .Relationship:  3   //RelationProcessorPackage
  39. .Reserved[0]:   //0x0000000000000000    0
  40. .Reserved[1]:   //0x0000000000000000    0
  41. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[5]
  42. .ProcessorMask: 0x000000000000000A  //10
  43. .Relationship:  0   //RelationProcessorCore
  44. .Reserved[0]:   //0x0000000000000001    1
  45. .Reserved[1]:   //0x0000000000000000    0
  46. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[6]
  47. .ProcessorMask: 0x000000000000000A  //10
  48. .Relationship:  2   //RelationCache
  49. .Reserved[0]:   //0x0000800000400801    140737492551681
  50. .Reserved[1]:   //0x0000000000000002    2
  51. .Cache.Level:   1
  52. .Cache.Associativity:   0x08    //8
  53. .Cache.LineSize:    0x0040  //64
  54. .Cache.Size:    0x00008000  //32768
  55. .Cache.Type:    2   //CacheData
  56. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[7]
  57. .ProcessorMask: 0x000000000000000A  //10
  58. .Relationship:  2   //RelationCache
  59. .Reserved[0]:   //0x0000800000400801    140737492551681
  60. .Reserved[1]:   //0x0000000000000001    1
  61. .Cache.Level:   1
  62. .Cache.Associativity:   0x08    //8
  63. .Cache.LineSize:    0x0040  //64
  64. .Cache.Size:    0x00008000  //32768
  65. .Cache.Type:    1   //CacheInstruction
  66. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[8]
  67. .ProcessorMask: 0x000000000000000A  //10
  68. .Relationship:  2   //RelationCache
  69. .Reserved[0]:   //0x0004000000400802    1125899911038978
  70. .Reserved[1]:   //0x0000000000000000    0
  71. .Cache.Level:   2
  72. .Cache.Associativity:   0x08    //8
  73. .Cache.LineSize:    0x0040  //64
  74. .Cache.Size:    0x00040000  //262144
  75. .Cache.Type:    0   //CacheUnified
  76. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[9]
  77. .ProcessorMask: 0x000000000000000F  //15
  78. .Relationship:  2   //RelationCache
  79. .Reserved[0]:   //0x0030000000400C03    13510798886308867
  80. .Reserved[1]:   //0x0000000000000000    0
  81. .Cache.Level:   3
  82. .Cache.Associativity:   0x0C    //12
  83. .Cache.LineSize:    0x0040  //64
  84. .Cache.Size:    0x00300000  //3145728
  85. .Cache.Type:    0   //CacheUnified
  86. SYSTEM_LOGICAL_PROCESSOR_INFORMATION[10]
  87. .ProcessorMask: 0x000000000000000F  //15
  88. .Relationship:  1   //RelationNumaNode
  89. .Reserved[0]:   //0x0000000000000000    0
  90. .Reserved[1]:   //0x0000000000000000    0
  91. GetLogicalProcessorInformation results:
  92. Number of NUMA nodes: 1
  93. Number of physical processor packages: 1
  94. Number of processor cores: 2
  95. Number of logical processors: 4
  96. Number of processor L1/L2/L3 caches: 4/2/1
 
参考:http://blog.csdn.net/dai_jing/article/details/37692643

使用GetLogicalProcessorInformation获取逻辑处理器的详细信息(NUMA节点数、物理CPU数、CPU核心数、逻辑CPU数、各级Cache)的更多相关文章

  1. php反射机制获取未知类的详细信息

    使用ReflectionClass就可以获取未知类的详细信息 demo: require("hello.php"); $class = new ReflectionClass(&q ...

  2. android笔记---百度地图api应用 (二) 获取公交路线的详细信息

    package com.example.bdtest; import com.baidu.mapapi.MKEvent; import com.baidu.mapapi.MKPlanNode; imp ...

  3. PHP怎么获取系统信息和服务器详细信息

    https://zhidao.baidu.com/question/1435990326608475859.html 获取系统类型及版本号: php_uname() (例:Windows NT COM ...

  4. 微信小程序开发(十一)获取手机的完整详细信息

    // succ.wxml <view style='position:absolute; top:30%; left:35%;font-size:36rpx'>{{name}}:签到成功. ...

  5. zTree获取当前节点的下一级子节点数

    使用zTree插件实现树形图中,需要获取当前点击的父节点的子节点数的需求,使用treeNode.children获取子节点数据集合,使用length方法获取集合长度.将当前节点的treeNode传入即 ...

  6. 【Android Developers Training】 99. 获取联系人详细信息

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 01.阿里云SDK调用,获取ESC主机详细信息

    一:通过python SDK获取云主机的详细信息 1.创建Accessky码(不做展示) 2.通过pip安装SDK模块,这个阿里云帮助里面有,也不做详细展示. 3.详细使用方法看代码 我下面展示的返回 ...

  8. PHP获取当前服务器详细信息

    最近正在用PHP写一个企业级的CMS,后台需要用到PHP获取当前服务器的详细信息以及相关系统参数信息,整理了整理,现在贴这儿,以备后用. 获取系统类型及版本号:    php_uname() (例:W ...

  9. 查看LINUX 系统硬件等详细信息

    转载这位朋友[地址] 几个cpu more /proc/cpuinfo |grep "physical id"|uniq|wc -l 每个cpu是几核(假设cpu配置相同) mor ...

随机推荐

  1. 使用Linux的命令行工具做简单的文本分析

    Basic Text Analysis with Command Line Tools in Linux | William J Turkel 这篇文章非常清楚的介绍了如何使用Linux的命令行工具进 ...

  2. 统计学习导论:基于R应用——第四章习题

    第四章习题,部分题目未给出答案 1. 这个题比较简单,有高中生推导水平的应该不难. 2~3证明题,略 4. (a) 这个问题问我略困惑,答案怎么直接写出来了,难道不是10%么 (b) 这个答案是(0. ...

  3. java自定义对话框

    package com.matp.view; import java.awt.FlowLayout; public class SimpleDialog extends JDialog impleme ...

  4. 构建服务端的AMD/CMD模块加载器

    本文原文地址:http://trock.lofter.com/post/117023_1208040 . 引言:  在前端开发领域,相信大家对AMD/CMD规范一定不会陌生,尤其对requireJS. ...

  5. Java中如何分析一个案列---猫狗案例为例

    猫狗案例: 具体事务: 猫.狗 共性: 姓名.年龄.吃饭 分析:从具体到抽象 猫: 姓名.年龄--->成员变量 吃饭       ---> 成员方法 构造方法:无参.有参 狗: 姓名.年龄 ...

  6. Js 通过点击改变css样式

    通过js 点击按钮去改变目标原始的背景颜色 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> ...

  7. ASP.NET实现从服务器下载文件2

    转:http://lanhy2000.blog.163.com/blog/static/436786082011105104110713/    假设在服务器的根目录下有个名为Download的文件夹 ...

  8. MSChart使用之动态生成多个多行ChartArea

    前台代码: <asp:Chart ID=" > <Titles> <asp:Title Name="Title1" runat=" ...

  9. 动态插入图片到 svg 中

    动态插入图片到 svg 中使用 createElementNS 来创建svg标签,通过setAttributeNS 来设置属性, 要注意两点,创建的时候要有'http://www.w3.org/200 ...

  10. 【NOI2006】最大获利

    [问题描述] 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU 集团旗下的CS&T 通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就 ...