🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
本文由[CPU阿甘](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513017&idx=1&sn=5550ee714abd36d0b580713f673e670b&scene=21#wechat_redirect)改编而得,主要讲的是系统启动和程序执行时CPU做的工作。 # CPU的构成 中央处理器(CPU,Central Processing Unit)由运算器、控制器、Cache等。 - 控制器:主要是对指令进行译码。 - 运算器:主要是执行定点或者浮点运算等。 - 寄存器:主要功能是保存计算的中间结果 可以看出CPU的主要功能是接收指令,执行指令。不过CPU不能保存指令。 最大的优点在于**速度快**,以ns为单位,内存比它慢了100倍,硬盘比它慢了1000多万倍。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-d14693dc90f53efa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 下面我们主要介绍一下计算机从加电到加载操作系统中,CPU主要做了什么事情。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-1d62af8f10be35d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 启动 当计算机上电了以后,CPU就先会执行**内存最顶端的指令**,现是一条**跳转指令**,所以会去执行BIOS里面的代码。 我们知道BIOS的主要功能是**系统自检**,看看内存、硬盘、显卡等是否有问题。自检完成以后,会产生**中断**,BIOS会告诉CPU是多少号中断。 中断了以后,CPU怎么知道去哪里执行响应中断的指令呢?我们可以用一张表来保存中断指令的响应代码,但是为了让这张表不那么臃肿,可以让这张表只保存响应代码的**入口地址**。 比如 | 中断类型号 | 响应指令的地址 | |-|-| | 0x01 | 地址A | | 0x02 | 地址B | | …… | …… | 这张表就称为**中断向量表**,保存的是响应中断的指令的**入口地址**,类似于响应代码的房间号。 CPU可以通过**中断向量表**查找到对应的指令,这条指令的目的是把**磁盘的第一扇区(磁盘的BIOS)运到内存中**。 到目前为止,硬件的初始化就完成了,下面应该加载**操作系统** ![image.png](http://upload-images.jianshu.io/upload_images/1323506-038a75f52b71b210.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 运行程序 操作系统加载入内存中以后,会接管整个系统的管理工作。 下面我们来谈一下如何运行程序。 首先操作系统会为CPU分配进程,不过对CPU而言,它只关心自己的**寄存器**和**程序计数器** - 寄存器:工作现场,包括一些计算的中间结果 - 程序计数器:要执行的下一条指令的地址。 要运行程序,首先需要从硬盘上加载程序。但是从硬盘上读程序实在太慢,CPU没有必要一直等着它,完全可以异步处理。 硬盘把返回的数据通过**直接内存访问(DMA)**把数据装载到内存中。这样CPU就解放出来,切换到另一个进程里面,当然相关的运行环境(寄存器、程序计数器)发生了改变。 但是上一个进程不可能放弃不执行了吧,所以等到当上一个进程的数据已经装载到了内存以后,CPU会收到一个中断,这样就可以切换回去了。 总结一下CPU的主要工作是,从内存中取出指令,进行译码,分解成为一系列的**微操作**,然后发出各种控制命令。 对CPU而言,主要关心的是它的寄存器和程序计数器,其中寄存器保存了计算的中间结果,而程序计数器可以用告诉CPU下一条指令去那里执行。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-10221d16ac2b1cb1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 性能参数 CPU的主要性能参数有: - 主频:表示CPU内数字脉冲信号震荡的速度,与实际的运算速度没有直接的联系,比如1GHz的Itanium芯片与2.66GHz的至强芯片一样快,因为CPU的运算速度除了有主频的因素,还有CPU的流水线、总线等各方面的影响。 - 外频:CPU的基准频率,MHz,可以决定**主板**的运行速度,如果把CPU超频了,可以CPU与主板会异步运行,所以整个系统有可能不稳定,一般来说服务器CPU不允许超频。 - 总线频率:指的是前端总线的频率,而前端总线指的是CPU与北桥之间的总线。 那么总线频率其实直接影响**CPU与内存的之间的交互速率**,即每秒CPU能接收的数据传输量。这点与外频不一样,外频是整块主板的运行速度。 - Cache:因为CPU与内存之间存在速度差,同时我们发现程序的加载有**局部性**的特点,也就是说一个内存位置被访问了,附近的位置很快也会访问到。那么我们完全可以把内存中的部分代码提前加载到Cache里面。 既然Cache的主要作用是CPU与内存的缓冲层,那么Cache的速度应该接近于CPU,基本上是与CPU同频运作。 缓存都集成在CPU芯片上,而CPU单位面积的价格很昂贵,Cache一般都很小。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-d77c55bf5e50eaae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 指令集 我们知道CPU的主要功能是解析指令,执行指令,也就是说CPU是靠一条一条的指令来计算和控制整个系统的。 也就是说不管是什么CPU,都有与之相匹配的指令系统。常用的指令集有两种 - 复杂指令集:一般来说程序的指令是按照顺序串行执行的,而指令中的各个操作也是串行执行的。这样控制简单,但是利用率不高。 x86架构的CPU主要使用的就是复杂指令集,AMD属于后起之秀,所以一定会兼容x86架构,它也是复杂指令架构的。 - 精简指令集: 复杂指令集最大的缺点在于微处理器太过复杂,所以研发成本高。而精简指令集,顾名思义,其指令系统得到大量的精简,而且指令格式统一,所以可以使用流水线结构,处理速度就上去了。 服务器中采用RSIC指令的CPU主要有:PowerPC、MIPS处理器。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-a2a448c9fb9ad992.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 处理技术 本章主要介绍一下CPU体系架构里面常用的技术 ## 流水线 每条指令都会经过取指(Fetch),译码(D1, main decode),转址(D2, translate),执行(EX, execute),写回(WB)结果等步骤。 那么当CPU预取完毕,进行译码的时候,预取部分的电路单元其实是空闲的。那么能不能让下一条指令进来执行预取的过程呢?答案是完全可以。 如下图所示,我们可以每过一个周期放入一条指令,这样在第5个时刻,最开始放入的指令其实已经执行到了最后一步WB了,第2条进入执行的指令比它晚一拍,执行到了EX上,其他的一次类推。 这样不断的有新的指令进入,同一时刻5条指令都在执行,只是说他们执行的阶段不一样。这样就实现了并行处理。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-0c4063a11b5031f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)