第九篇 -- cpu的学习
CPU的核数关系:
总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l # 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq # 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
C++获取系统中CPU的总逻辑CPU数:
// CPUCoreNumber.cpp : This file contains the 'main' function. Program execution begins and ends there.
// #include "pch.h"
#include <iostream>
#include "windows.h"
using namespace std; /****************************************************函数声明部分*******************************************************/
void GetCPUCoreNum(); /****************************************************主函数,即入口函数**************************************************/
int main()
{
//1. 获取CPU的逻辑核数
GetCPUCoreNum();
} /***********************************************************************************************************************/
/* 普通函数 */
/***********************************************************************************************************************/ //获取CPU的总核心数
void GetCPUCoreNum() {
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
printf("now system cpu num is %d\n", sysInfo.dwNumberOfProcessors);
}
检测方法:
在cmd命令中输入“wmic”,然后在出现的新窗口中输入“cpu get *”

NumberOfCores:表示CPU核心数
NumberOfLogicalProcessors:表示CPU线程数,也可以说是逻辑处理器的个数
根据上面的检测方法,可以获取CPU的物理个数
// CPUCoreNumber.cpp : This file contains the 'main' function. Program execution begins and ends there.
// #include "pch.h"
#include <iostream>
#include "windows.h"
using namespace std; /****************************************************函数声明部分*******************************************************/
void GetCPUCoreNum();
int GetPhyCpuNum(int &num); /****************************************************主函数,即入口函数**************************************************/
int main()
{
//1. 获取CPU的逻辑核数
//GetCPUCoreNum(); //2. 获取CPU物理个数
int num = 0;
GetPhyCpuNum(num);
cout << num << endl;
} /***********************************************************************************************************************/
/* 普通函数 */
/***********************************************************************************************************************/ //获取CPU的总核心数
void GetCPUCoreNum() {
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
printf("now system cpu num is %d\n", sysInfo.dwNumberOfProcessors);
} //获取CPU物理个数
int GetPhyCpuNum(int &num)
{
// -------------------- 得到当前路径 ---------------------
char path[256] = { 0 };
char exePath[256] = { 0 };
GetModuleFileName(NULL, exePath, sizeof(exePath));
printf("%s\r\n",exePath); int len = 0;
len = strlen(exePath); int i;
for (i = len - 1; i > 0; i--)
{
if (exePath[i] == '\\')
break;
}
if (i == 0)
return -1;
else
{
strncpy_s(path, exePath, i + 1);
strcat_s(path, "cpuinfo.txt");
} // ------------------- 发送wmic命令查询 结果放到文件中-------------------
//printf("%s\r\n",path);
char cmd[512] = { 0 };
sprintf_s(cmd, 512, "wmic cpu get > %s", path);//printf("%s\r\n",cmd);
system(cmd);
Sleep(3000); // ------------------- 读文件内容到数组中 -------------------
FILE *fp = NULL;
int fileLen; fopen_s(&fp, path, "r");
if (fp == NULL)
{
return -2;
}
fseek(fp, 0, SEEK_END); // 定位到文件末
fileLen = ftell(fp); // 得到文件大小
if (fileLen == 0)
{
fclose(fp);
return -3;
}
fseek(fp, 0L, SEEK_SET); // 定位到文件开头
char *buffer = new char[fileLen + 1];
fread(buffer, fileLen, 1, fp); // 一次性读取全部文件内容
buffer[fileLen] = '\0'; // 字符串结束标志
fclose(fp); // ------------------- 查询行数 -----------------------------
i = 0;
int n = 0;
while (i < fileLen)
{
if (buffer[i] == '\r')
n++;
i++;
} num = n - 1; // 第一行是列名,要减去
delete buffer;
return 0;
}
看到这里可以发现,CPU的逻辑数,物理数都可以用第二种方法得到。
关于CPU MMX/SSE参考链接:
https://www.cnblogs.com/dragon2012/p/3731931.html
https://blog.csdn.net/thinkwell12/article/details/4466423
关于CPU的寄存器理解:
汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊?
eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。
EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。
ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
EDX 则总是被用来放整数除法产生的余数。
ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.
EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
push ebp ;保存当前ebp
mov ebp,esp ;EBP设为当前堆栈指针
sub esp, xxx ;预留xxx字节给函数临时变量.
...
这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.
ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。
386部分寄存器:

状态和控制寄存器组除了EFLAGS、IP ,还有四个32位的控制寄存器,它们是CR0,CR1,CR2和CR3。
这几个寄存器中保存全局性和任务无关的机器状态。
CR0中包含了6个预定义标志,0位是保护允许位PE(Protedted Enable),用于启动保护模式,如果PE位置1,则保护模式启动,如果PE=0,则在实模式下运行。1位是监控协处理位MP(Moniter coprocessor),它与第3位一起决定:当TS=1时操作码WAIT是否产生一个“协处理器不能使用”的出错信号。第3位是任务转换位(Task Switch),当一个任务转换完成之后,自动将它置1。随着TS=1,就不能使用协处理器。CR0的第2位是模拟协处理器位 EM (Emulate coprocessor),如果EM=1,则不能使用协处理器,如果EM=0,则允许使用协处理器。第4位是微处理器的扩展类型位ET(Processor Extension Type),其内保存着处理器扩展类型的信息,如果ET=0,则标识系统使用的是287协处理器,如果 ET=1,则表示系统使用的是387浮点协处理器。CR0的第31位是分页允许位(Paging Enable),它表示芯片上的分页部件是否允许工作。
CR1是未定义的控制寄存器,供将来的处理器使用。
CR2是页故障线性地址寄存器,保存最后一次出现页故障的全32位线性地址。
CR3是页目录基址寄存器,保存页目录表的物理地址,页目录表总是放在以4K字节为单位的存储器边界上,因此,它的地址的低12位总为0,不起作用,即使写上内容,也不会被理会。
这几个寄存器是与分页机制密切相关的,因此,在进程管理及虚拟内存管理中会涉及到这几个寄存器,读者要记住CR0、CR2及CR3这三个寄存器的内容。
位 标号 解释
0 FPU Floating Point Unit On-Chip. CPU是否内置浮点计算单元
1 VME Virtual 8086 Mode Enhancements. 是否支持虚拟8086模式
2 DE Debugging Extensions. 是否支持调试功能.
3 PSE Page Size Extension. 是否支持大于4MB的分页.
4 TSC Time Stamp Counter. 是否支持RDTSC指令.(注:RDTSC指令可以计算出CPU的频率)
5 MSR Module Specific Registers RDMSR and WRMSR Instructions. 是否支持RDMSR与WRMSR (*注1)
6 PAE Physical Address Extension. 是否支持大于32bit的物理地址.
7 MCE Machine Check Exception. (*注2)
8 CX8 CMPXCHG8B Instruction. 是否支持8bytes(64bit)数的比较与交换指令.
9 APIC APIC On-Chip.是否支持APIC(Advanced Programmable Interrupt Controller)
10 保留
11 SEP SYSENTER and SYSEXIT Instructions.是否支持SYSENTER与SYSEXIT指令.(*注3)
12 MTRR Memory Type Range Registers. 是否支持MTTR(*注4)
13 PGE PTE Global Bit. 是否支持全局页面目录入口标志位 (global bit in page directory entries)
14 MCA Machine Check Architecture. 是否支持MCA,MCA是Pentium4,Xeon,P6级处理器的一个错误报告机制
15 CMOV Conditional Move Instructions. CMOV指令是否可用.(请问谁可以解释一下CMOV是什么命令?)
16 PAT Page Attribute Table. 是否支持PAT,PAT允许操作系统指定4K大小的线性内存空间
17 PSE-36 32-bit Page Size Extension. 是否支持4GB的扩展内存
18 PSN Processor Serial Number. 是否支持处理器序列号.(P3有效)
19 CLFSH CLFLUSH Instruction.是否支持CLFLUSH.(*注5)
20 保留
21 DS Debug Store. 是否支持把调试信息写入缓存,
22 ACPI ACPI Processor Performance Modulation Registers. 处理器使用特别的寄存器以允许软件控制处理器的运行周期.
23 MMX Inter MMX Technology.是否支持MMX
24 FXSR FXSAVE and FXRSTOR Instructions. FXSAVE与FXRSTOR指令是否可用(*注6)
25 SSE SSE.是否支持SSE.
26 SSE2 是否支持SSE2.
27 SS Self Snoop. 处理器是否支持总线监视,以防止储存器冲突.
28 保留
29 TM Thermal Monitor.CPU是否支持温度控制.
30 & 31 保留
解释:
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个“逻辑处理器数”。
另外,学习小提示
1. 可以谷歌搜索资料,关于CPUID部分,资料会比百度上多一些。https://c9x.me/x86/html/file_module_x86_id_45.html
2. 可以进入Intel官网,查到相关CPU,然后点击datasheet,里面会有关于CPU的文档,并且可以将代码得到的结果与官网上进行比较,可以初步判断代码是否有误。
3.中文翻译部分文档:http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User%27s%20Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc46.htm
2019/7/10
学习CPU进程线程相关:https://blog.csdn.net/flyingleo1981/article/details/15812141
可以调用GetProcessAffinityMask函数来取得一个进程相关性屏蔽信息。
BOOL GetProcessAffinityMask(
HANDLE hProcess,
PDWORD_PTR pdwProcessAffinityMask,
PDWORD_PTR pdwSystemAffinityMask);
该函数通过第二个参数返回指定进程的CPU的相关性信息,同时可以通过第三个参数返回系统相关性信息。系统相关性指明系统的哪些CPU可以处理线程,进程的相关性始终是系统相关性的子集。
第九篇 -- cpu的学习的更多相关文章
- Egret入门学习日记 --- 第九篇(书中 2.7~2.8节 内容)
第九篇(书中 2.7~2.8节 内容) 昨天记录到了 2.6节 ,那么今天就从 2.7节 开始. 这个 2.7节 有7个小段,有点长,总结一下重点: 1.调试项目的两种方法. 2.运行项目的两种窗口选 ...
- 20145330第九周《Java学习笔记》
20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...
- 第九篇 SQL Server代理了解作业和安全
本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这一系列的上一篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本 ...
- 第九篇 Integration Services:控制流任务错误
本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...
- [老老实实学WCF] 第九篇 消息通信模式(上) 请求应答与单向
老老实实学WCF 第九篇 消息通信模式(上) 请求应答与单向 通过前两篇的学习,我们了解了服务模型的一些特性如会话和实例化,今天我们来进一步学习服务模型的另一个重要特性:消息通信模式. WCF的服务端 ...
- ElasticSearch入门 第九篇:实现正则表达式查询的思路
这是ElasticSearch 2.4 版本系列的第九篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- 【译】第九篇 Integration Services:控制流任务错误
本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...
- 【译】第九篇 SQL Server代理了解作业和安全
本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这一系列的上一篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本 ...
- 20155234 2610-2017-2第九周《Java学习笔记》学习总结
20155234第九周<Java学习笔记>学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC(Ja ...
随机推荐
- Redundant Paths 分离的路径
Redundant Paths 分离的路径 题目描述 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她 ...
- [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark
[源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 0x0 ...
- git schnnel failed to receive handshake, SSLTLS connection failed
git schnnel failed to receive handshake, SSLTLS connection failed 报错,查看原因为git安装时ssl选择的不是openssl.重新安装 ...
- 单链表(LinkedList)
与数组相似,链表也是一种线性数据结构.这里有一个例子: 正如你所看到的,链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起. 链表有两种类型:单链表和双链表 ...
- 利用C语言输出一个二元一次函数
#include<stdio.h> #include<math.h> int main(void)//其实void我认为在这可有可无 { double a,b,c,x1,x2 ...
- Java数据库开发(二)之——DBCP连接数据库
1.载入jar包 DBCP需要以下几个jar包,可到apache及mysql的官网下载 2.程序编写 public static BasicDataSource ds = null; static f ...
- Centos-Springboot项目jar包自启动
CentOS环境下部署Springboot项目的jar包开机自启动. 部署环境 Centos 7.5 Springboot 2.1.x 操作步骤 修改pom 在pom.xml文件中<plugin ...
- namenode和datanode启动失败
1.namenode启动失败,查看错误原因,是无法格式化,再看日志,根据日志提示,清空对应的目录,即可解决这个问题. 2.datanode启动失败: Can't open /var/run/cloud ...
- spring boot j集成seagger 加入拦截器后 swagger 不能访问
一开始我是这样排除拦截的,但是发现没用 后来我发现swagger的真实访问路径是这样的 转自: https://blog.csdn.net/ab1991823/article/details/7906 ...
- Leetcode No.121 Best Time to Buy and Sell Stock(c++实现)
1. 题目 1.1 英文题目 You are given an array prices where prices[i] is the price of a given stock on the it ...