前一篇计算机系统006 - 硬件组件之RAM中讲完五大组件中的RAM部分,剩下最后的硬骨头CPU还未说明,本篇就试着对其进行尽量完整的剖析。 编程
开篇以前,放一张CPU全貌镇场。
缓存
工艺很好,封装很完整,除了一排排针脚,再看不出来其余东西,所幸透过外壳,一探究竟(以Intel Haswell为例)。
函数
说实在的,要是不标英文注释,我也不知道这里面每一个区域放的是什么。不过既然有,总比没有好,这里暂不讨论商业化成熟的CPU方案全部内容,只关注以下两个部分: post
SHARED L3 CACHE
若是还能记得上一期所述的存储器层级图的话,那么你应该能注意到,SHARED L3 CACHE下面一级是MEMORY CONTROLLER IO,也就是说,这一级能够视为Cache,而下一级链接的是RAM,它的上一级又是CORE。因为以前已经对Cache的来由和原理作了讲解,这里就不在赘述。性能
CORE
CORE其实是CPU的基础计算单元(注意这里说的是计算单元,而非控制单元或处理单元),它能够运行单个进程,维护进程状态、寄存器值、确保正确的执行次序,以及经过ALU执行操做。一个CPU一般由一至多个CORE,俗称“多核”,上图所示的CPU中就含有4个CORE,所以也称4核。
既然每一个CORE能够单独运行进程,那么在预算范围内天然是越多越好。不过也应当知道,4核CPU总体性能并不能简单换算成单核乘以4,先不论软件上是否作了支持以即可以均摊在4核上跑满,单说4核相互间也必须经过L3 Cache交换信息,就能够知道在交换上会耗费一部分开销。 优化
在第4篇 中介绍CPU部分时,给出了下面这张图。
编码
从图中能够看出,CPU是由ALU、CU、Memory三部分组成,而CORE能够单独执行整个进程,且CPU从一开始也是单核形式存在,因此这里能够等同认为CORE也是由ALU、CU、Memory三部分组成。 操作系统
ALU也称为算术逻辑单元,是用于执行二进制表示整型的算术和按位运算组合数字电路。ALU是许多计算电路的基础模块,与之相对的是FPU(Floating-point unit)浮点单元,FPU处理的是浮点数值。 设计
以计算“1+2”为例,其原理以下图所示:
指针
Integer Operand A, B
A,B均为输入运算对象,分别为 1(01),2(10)
Opcode
运算符,做用于运算对象。此处为‘+’。虽然opcode与机器语言opcode在感念上有所区别,但一般会等同使用。
Status(可选)
可选状态值,输入输出均为状态寄存器,在ALU进行计算时,可能须要参考其中标志如CF判断是否有进位,同时在结果中设置该flag
Integer Result
整型结果,输出门电路交换后值,此处为3(11)
包括上述加法操做,ALU一共支持以下类型操做:
每个Opcode都对应着不一样的电路实现,相互间存在着逻辑门、触发器等各类实现差别。而从ALU的使用原理上能够看出,要想完成计算,需以下前提条件:
为了提供这三类值,就必须先和寄存器打交道。
Register也称为寄存器,总的来说,Register是Memory中SRAM的一种,优点在于快,劣势在于贵。
快的缘由在于无机械部件、无电容充放电,存取的全部过程均基于电路交换,也就是说电路频率有多快,理论上他就能够作到多快。不太高频电路中不管是元器件焊点,仍是布线都有可能对集成后电路总体性能和稳定性产生干扰,所以在频率上也经常有所限制。
设计寄存器时,并不是全部Register都以相同电路实现,而是会以所要实现的功能为目标进行取舍。一般,寄存器可分为以下几类:
MAR(Memory Address Register)
内存地址寄存器,保存数据或指令在内存中地址,挂载在地址总线上,用于在指令执行期间获取数据或指令。例如CPU但愿在内存中保存或获取内存中某一数据时,可将对应地址放在MAR中
PC(Program Counter)
程序计数器,在Intel X86中也称为指令指针IP(instruction pointer),始终指向下一条要执行的指令。
AC(Accumulator) Register
累加寄存器,保存CPU计算所得结果。
MDR(Memory Data Register)
内存数据寄存器,与MAR相似,区别在于挂载在数据总线上。MDR就能够从数据总线加载数据,也能够存储CPU中数据,就像一个Buffer同样保存着送往解码器(见1.3小节)前的信息。
MDR是配合MAR使用的,读取某一内存地址数据前,如今MAR中存放读取地址,发送读信号,就能够在MDR中获取目标值;一样在MAR中存入目标地址,MDR中存放要写入数据后,发送写信号,便可往内存中写出数据。也就是说,MDR和MAR共同组成了CPU对内存部分的访问接口。
Index Register
变址寄存器,存放从基址起要偏移的地址数,用于在程序运行过程当中调整操做符地址。
MBR(Memory Buffer Register)
缓存寄存器,存放已经读取或写入内存的数据或指令内容,起缓存做用。
Data Register
微型计算机中用于临时存放传输给,或读取自其余外围设备数据的数据。
固然,上述寄存器大可能是控制单元CU内部使用,对于用户,可见的寄存器类型为通用寄存器,以8086为例,可见的寄存器以下:
累加寄存器 | AX |
基址寄存器 | BX |
计数寄存器 | CX |
数据寄存器 | DX |
栈指针寄存器 | SP |
基址指针寄存器 | BP |
源变址寄存器 | SI |
目的编制寄存器 | DI |
事实上,每一个寄存器的背后都有独立的电路实现,而不一样类型的寄存器实现每每各不相同。所以,编程时并不是强制让你使用某个寄存器,而是因为该寄存器设计时电路实现所限,它只支持部分功能。例如寻址时只能使用BX、BP、SI、DI,不是故意刁难,标新立异,而是由于只有这些寄存器在电路实现时对寻址作了支持。
一样,一个进程运行后,会有对应状态值,如指令指针、AF、CF、ZF等等标志位,均存储在对应寄存器中。CPU只会循环读取下一条指令地址,进行计算,所以只要在读取下一条指令地址前,将其替换成新进程的指令指针,便可完成进程切换。固然为了确保能顺利回来,还必须在替换前保存现有进程状态。
到如今为止,咱们有了支持不一样运算操做(Opcode)的ALUs,也有了不一样用途存储不一样数据的寄存器Registers,为了实现进一步的自动化计算,应该开始考虑控制单元CU的内部逻辑了。
计算的实质是接收任务描述,按照任务描述的步骤,完成计算,并输出结果。回到任务描述自己,用户该如何描述一个任务以使得执行计算的计算机能够理解任务内容?
想象一下现实生活中,须要将某一任务托付给别人时,咱们一般须要以下步骤:
当对方是计算机时,上述步骤就变成:
从前面咱们了解了ALU的运算方法和寄存器如何从内存中加载数据,所以这里只考虑寄存器、ALU、CU三者之间的交互。对于此时的CU来说,寄存器中已经给出了可执行文件在内存中的入口地址,起点已经有了,接下来就是如何按照可执行文件内容顺利执行完整个任务。
CU就像CPU的大脑,负责全部控制行为。一般在CU内部,将计算任务执行过程分为以下三步:
取指(Fetch)
第一步,获取指令。程序内存中指令地址存储在程序计数器PC中,每次获取完指令后,PC自动加上所获取到指令的长度,也就是指向下一条指令处。一般指令来源于相对较慢的内存中,这会阻塞CU直到获取完成,好在现代处理器经过缓存或流水线技术极大缓解了该问题。
解码(Decode)
第二步,指令解码,指令解码的最终解释权归CU指令集ISA全部。指令的一部分为操做码,标明应该执行何种操做。其他部分一般会提供该操做所需的额外信息,如操做数等。
CU实现分电路和微编程两种,前者不可修改,但速度比微编程实现更快,因为指令集修改后须要调整电路,代价较高,所以一般用于RISC精简指令集中;另外一方面,微编程CU简化告终构,下降了开发难度。
简而言之,就是任务描述中的指令(以汇编级别起始)来源于CPU指令集,其中每条指令在从内存中读取后进行解码,解码器将单条指令分解成一至多条微操做(Opcode),经过控制电路信号,选择指定ALU完成目标操做。
同时,须要注意上述三个步骤执行过程当中须要参考时钟脉冲,时钟脉冲有特定频率,电路被时钟脉冲的上升沿或降低沿所触发,造成统一步调。
上一节中对单个核心进行了探讨,但随着技术的发展,单核心的速度每每没法知足日益增加的计算需求,所以在CPU发展史上,也陆续出现了以下改进技术。
流水线技术的前提是操做可进一步分解,分解后的每一个步骤可独立运行。
不过须要注意的是,流水线技术并不能增长单个任务的处理效率,即每一个任务一样仍是须要5个时钟周期才能完成,甚至相反,反而会由于进行了任务分解而致使每一个步骤间需经过寄存器交换结果。
所以,从本质上来说,流水技术减小的是任务的平均等待时间,而非单个任务完成时间。
一般大的任务能够分解为小的任务,这样就能够同时进行处理以减小总体消耗时长。一般有以下3种并行计算方法:
位级别并行
经过增加处理器字长,减小了同一指令所需操做数目。如8位处理器在进行两个16位整型数加法时,须要先将低8位相加,再将高8位及进位相加,也就是说,须要两个操做才能实现一条指令。而若是使用16位处理器,就能够经过一个操做完成相同指令。这样一来,就减小了一半的执行时间。
指令级别并行
计算机程序其实就是一些列有序的指令,默认状况下,处理器每一个时钟周期内最多只能处理一条指令,而事实上,有的指令从新排序后并列执行并不会影响最终结果,所以彻底能够在指令级别实现部分并行以提升速度。
任务级别并行
同一程序的多个进程(程序运行实例,如感兴趣,后续操做系统部分会讲到)能够针对相同数据或不一样数据进行并行处理,甚至同一程序也能够将其子任务分发给不一样处理器进行处理。
改进至此,却发现不管CPU如何优化并行、流水线等技术,真正致使程序执行速率缓慢的缘由还在于CPU每执行一条指令,至少要与存储器交互一次,寄存器也好,内存也罢,它们的速率即便有了Cache或者分级存储机制,依然不可以有效弥补。为了可以最大限度地使用CPU,就须要对耗时严重的I/O操做进行优化。
传统模型里,执行一次I/O须要三个步骤:
从中能够看出,第1、三个步骤并未直接参与主存读写,耗时远比第二个步骤少,为了减小第二个步骤所消耗的CPU资源,因而从硬件层引入了中断机制。
中断能够经过单独控制器实现,也能够集成进CPU中。每一个中断有各自独立的编码,硬件上有具备相互独立的内存单元。当一个中断出现后,控制器在执行完当前指令后将切换程序至内置ISR(Interrupt Service Routine)或指定的中断处理程序,执行完毕后,再从新切回原执行程序。
至于如何完成CPU中断的进程切换,将在后面详细讲述,此处只说明为修改PC地址、从新载入进程被切换前各寄存器状态值便可。
CPU这一篇就写到这里,没有满屏的电路图,也没有什么高深的人与天然。我的看法来说,理解CPU本质仍是要回归到计算自己,包括计算实现、计算表示、以及自动化计算流程的分解。但愿可以有所收获,到本篇为止,硬件部分基本讲完,然而有硬件并不能成为计算机,因此下一篇中,将从操做系统开始提及。