哈喽,我是子牙老师。今天想写篇文章聊聊我对CPU的全部认识,你可以看看,里面有很多东西是你平时听过但不理解的,也有你没听过的
计算机考研408中,《计算机组成原理》估计是最难的,《计算机组成原理》中最抽象的估计就是与CPU相关的。这篇文章我提到的所有与CPU相关的技术,我都会举例帮你真正理解,考研党必看!
我们程序员写程序,都是面向API编程,当然也有面向百度谷歌编程的,现在是面向AI编程
那写操作系统呢?面向什么编程呢?它没有API可用啊!面向硬件接口编程!这些硬件包括BIOS/UEFI、主板、CPU、内存条、中断控制芯片、PCIe总线、硬盘、网卡…
你要想写操作系统,你首先得了解这些硬件的工作机制,再去研究如何利用它们提供的接口操控它们,再去编码实战。实战环境你可以选自己写的操作系统或写Linux内核驱动。
如果你想写操作系统,或者想实战编码操控硬件体验,可以咨询我做的课程《手写操作系统》或《实战Linux内核》,学完就能动手干
这篇文章分享最核心的硬件:CPU。其他硬件,后面写文章分享
我会从这些角度分享:
- 关于CPU架构的全部
- 关于CPU结构的全部
- 超线程技术及其在Linux内核中的应用
- CPU与汇编之间的关系
- SMP架构 VS NUMA架构
- CPU的运行模式
- CPU的特权级
- CPU的段页门
- CPU的快速调用
- CPU多核是如何被操作系统发现的
- CPU多核是如何被激活的
- CPU多核是如何通信的
- 实战:通过CPU接口控制CPU玩玩
- 多核多线程的操作系统是如何写出来的
不整理不知道,CPU居然有这么多东西…我会分成多篇文章讲解,感兴趣的关注公众号【硬核子牙】看此系列文章
以下,enjoy~
CPU架构
聊CPU架构,就不得不提到另外几个名词:指令集、汇编、机器码。这四个名词之间是什么关系呢?我直接讲你肯定没有概念,我通过一个例子结合起来讲
比如你盖房子,你首先得有一个定位:住宅还是写字楼还是商场,这三者的结构是完全不一样的。CPU架构就有点这个感觉。你想设计一个CPU,你选哪个架构:RISC还是CISC
RISC是简单指令集,CISC是复杂指令集。整个地球上,除了x86 CPU、x86-64 CPU是CISC架构,其他都是RISC架构,比如雷总经常提到的高通骁龙CPU、华为的麒麟CPU、小米的澎湃CPU、苹果的M系列CPU
我就不展开讲RISC、CISC了,它们的优缺点,感兴趣的小伙伴自行面向AI学习。但是为了让你更形象地理解它们,我还是举个例子:比如你想实现1+1
大概看出来区别了吧:CISC可以用更少的指令干更多的事。为什么可以如此呢?就要提到它的指令集了。讲完指令集,代码注释中的两个东西:NASM汇编、ARM汇编,才能解释清楚
回到例子,比如你确定了要建住宅,下一步是不是要画工程图纸。CPU的工程图纸,CISC架构的,只有两个选择:x86 32位指令集、x86-64 64位指令集。毫无疑问,现在CISC架构的CPU,全部都是x86-64指令集,简称x64指令集。RISC的,目前主流的是ARM指令集、RISCV指令集
基于CISC架构CPU的操作系统,32位的与64位的我都写过了,并做成了课程,感兴趣的可以找班主任【jvm-anan】咨询《手写x86单核OS》《手写x64多核OS》。手写ARM操作系统的课程,大概9月可以出来
CISC架构的CPU,一般都是用在个人PC及服务器上。生产CISC架构的CPU,全球主流是Intel、AMD。苹果的M系列CPU问世,打破了这个局面,因为M系列CPU是RISC架构的ARM指令集
大家都说RISCV指令集是未来,但是现在大家在玩的几乎都是ARM指令集。刚查了下,华为的鲲鹏系列CPU是基于RISCV指令集实现的
指令集就讲完了,接着走。回到例子,工程图纸有了,下一步干吗?是不是要采购工程材料。在计算机的世界里,机器码就是工程材料。
机器码长啥样?长这样
机器码为什么长这样?看图
机器码的用途在哪呢?我们正常写代码不会用机器码直接编程,而是使用更上层的汇编语言、C语言、C++等。但是做逆向写shell code、为了极致性能写编程语言的执行引擎、为了最强性能做编程语言后端优化,会使用机器码编制技术。这部分难不难呢?会者不难,难者不会。反正国内没人教,我的课程《手写编程语言》中教了
汇编呢?下一PA讲
总结一下,就是这张图
这四个名词之间的关系,你看懂(废)了吗?
CPU与汇编
如果直接使用机器码进行编程,无疑门槛太高,维护太难,所以诞生了上层的汇编语言,再往上诞生了C语言、C++,再往上Java、Python、PHP……
但是CPU只能运行机器码,无法直接运行汇编代码、C代码、C++代码,这就需要编译器的存在,将汇编代码、C代码、C++代码翻译成机器码,专业术语叫编译。反向技术就叫反编译,就是把机器码翻译成汇编代码、C代码、C++代码。
汇编代码、C代码、C++代码是无法跨平台运行的。不同编译器编译出来的是特定CPU架构的机器码。所以如果你玩过嵌入式,你会听到一个词:交叉编译,就是在一个平台(比如你的开发机 x86)上,为另一个平台(比如 ARM、RISC-V)生成可运行程序
Java、Python、PHP能跨平台的秘密相信你已经get到了,是因为它们的代码不是直接由CPU运行,是由特定的虚拟机去运行,而虚拟机可以编译成不同平台运行的版本
这就是学通底层的意义,底层通,上层一通百通!铺垫知识讲完,开始讲正题
CISC架构,对应的是x86 32位指令集、x64 64位指令集。对应的汇编风格有三种:NASM、MASM、ATT。Windows系统,MASM是主流,大小写不敏感。Linux系统,主要使用ATT、NASM。我个人不喜欢ATT,所以我用NASM比较多。但是内联汇编没办法,只能用ATT
RISC架构,对应的就是ARM指令集、RISC-V指令集,没有不同的汇编风格,所以可以直接称呼ARM汇编,RISCV汇编
以上便是编程语言的发展历史,及汇编与CPU架构、指令集、机器码之间的关系
CPU结构
目前主流的CPU都是多核,大概长这样
我这个画的是开启了超线程技术的CPU。如果没有开启,一个CPU核只有一个逻辑线程。但是现在的CPU默认都是开启的
我记得以前经常有人问我:子牙老师,随着调度发生,同一个CPU会运行不同的程序,为什么不会发生错乱呢?如果你能看懂这个图,你就知道答案了
这张图中提到的名词,你面向AI去学习,能够得到答案,但是你可能没有概念
如果你想有概念,可能需要一些功底,比如能够熟练的玩汇编、对执行流有深刻的理解、对线程切换有深刻的理解……如果你没有,可以看看我讲的汇编教程。关注公众号【硬核子牙】回复【汇编教程】免费领取
关于CPU多核是如何被操作系统识别的、CPU多核是如何激活的、CPU多核间是如何通信的……下篇见。关注公众号【硬核子牙】,看更多硬核文章
超线程技术
超线程技术,英文Hyper-Threading,所有又叫HT技术
前面提到,我上面画的图是开启了超线程技术的。超线程技术是一种什么感觉呢?就像开了分身。只不过有的东西是独享的,有的东西是共享的。你看过火影没,长门的六人组,大家身体是独享的,但是视野是共享的,就是这种感觉
注意一下,不是所有的CPU核都支持超线程技术。比如我的电脑,12核,但是只有20线程,为什么会这样呢?
因为从成本与性能角度做了权衡,现在的CISC架构的CPU多采用混合架构,不是所有的核都支持超线程技术。支持超线程技术的核称为P-Core,不支持的称为E-Core。所以12核20线程是怎么算出来的,你知道了吗?8个p-Core,4个E-Core
这里的线程是硬件线程,我们平时提的线程是操作系统线程,它们不是一个东西,大家可别混淆了
顺便提下,因为CISC架构的CPU多运行在插电的设备上,对功耗没那么敏感,所以可以采用混合架构。但是RISC架构的CPU,多用在需要省电的设备上,比如手机、冰箱、无人机…所以ARM高性能CPU,多采用异构架构,即你可能听过也可能没听过的大小核。
Linux内核源码难读的地方就在这里,你需要对硬件工作机制非常了解,不然相关代码根本看不懂
调度器的职责就是调度某个线程,在某个CPU上,运行多少CPU时间,所以在调度的时候,需要为线程选核。Linux内核怎么做的呢?引入了CPU拓扑分层结构。
为线程选核是一个非常复杂的过程。Linux内核中的选核机制,我之前写过一篇文章《你打算派哪个CPU来运行我》,感兴趣的可以去看看
上面的图画的是SMP架构,如果是NUMA架构呢?长这样。架构层面看只是多了一层,代码层面复杂了一个数量级!写线程切换与调度代码的人,真的非常非常牛
又引出两个新名词:SMP架构,NUMA架构,它们是什么呢?
SMP VS NUMA
SMP架构,统一内存访问模型,长这样
NUMA,非一致内存访问结构,长这样
它们的区别是什么呢?通俗来说,SMP架构是所有CPU共享一块内存,而NUMA架构是某几个CPU共享某一段内存。比如0-3号CPU共享内存的0-0x1000000区域,它们在一起组成一个NUMA NODE 0,4-7号核共享内存的0x1000000-0xffffffff,它们在一起组合成NUMA NODE 1
是不是没有概念?让你有概念一点
这样运行,Linux内核就是NUMA架构模式。把5G内存定义成了两个内存节点:mem0、mem1,然后定义了两个NUMA节点:0-1号核与mem0组成一个NUMA节点,2-3号核与mem1组成一个NUMA节点
其实我们平时用的电脑都是SMP架构,甚至说我们普通人几乎没有机会接触到NUMA架构的电脑,那NUMA架构的电脑谁在用呢?需要大量运算的地方!比如研究所、大型服务器…
Linux内核是基于NUMA架构设计的,很多地方有NUMA相关的代码,这也是我之前花大量时间研究NUMA的原因所在,因为你对NUMA没概念,看代码看得迷迷糊糊的,心里不踏实
比如Linux内核的内存模型,长这样。你可能想问:那SMP架构怎么办?SMP架构当成是只有一个节点的NUMA架构不就可以了,Linux内核就是这么干的
如果你掌握了单步调试Linux内核的技术,你就可以单步调试Linux内核去论证我说的,我自己来论证一下我说的都是对的
至此,把CPU看成一个整体,它与外部相连的所有东西就讲完了,下篇文章讲CPU的内部,讲完再带你写代码控制CPU…
关注公众号**【硬核子牙】**,看后续精彩
其实技术这行是有无限乐趣的,但是得你的水平到一定程度。到哪个程度呢?就是你学通了,学深了,想干什么就能干什么的时候。现实世界中,我们想做什么就做什么是很难做到的,但是计算机的世界,我们是有机会做到的,我做到了。所以我越来越喜欢计算机,每次做出别人不愿意或做不了的课程,那种内心世界,站在山巅向下俯视的感觉,仿佛能体会到看毛主席的诗,那种大气磅礴的感觉…俱往矣,数风流人物,还看今朝!