阅读 153

CPU的工作原理 - 运行流程

我们大多使用的是Intel或者AMD的CPU,但是本文只以《But How Do It Know》书中给出的一个简略版的CPU(称为Scott CPU)为例来介绍CPU的每个部件和其工作的原理。

如下图所示,这是一个CPU的内部,外壳和底面:

image-20210821221532022.png

CPU下面由许多引脚,用来连接芯片和主板上的其他配件。我可以看到主板上存在一些排线分别对应着三大总线:地址总线、数据总线和控制总线。通过这些总线相连接的是我们的外部设备,比如最右侧的RAM就是我们内存条插槽处。最左侧是其他的一些外接设备的插槽,比如显示器,键盘等。

image.png

与RAM交互

我们先看看CPU是如何和RAM进行交互的。

image.png

图片是一个256字节大小的RAM,它一共可以分为3块引线:address,data,(set&enable)正好是对应着主板上的三大总线。

我们可以粗略的将RAM中的内存存储的数据结构分为2个部分:一部分是地址,一部分是数据(分别对应着图片白色和灰色的部分)。我们可以看到这些地址或者数据都是只有8位的,因为我们的地址总线和数据总线的条数也都只有8位。

RAM中的存储的数据都是0和1,他们对应的可能是数字,字符,指令,还有地址。

  • 指令:CPU的主要工作就是执行程序,程序是由一些列单独的操作组成的。这些操作称为指令。CPU运算中最重要的就是指令,是指令告诉CPU下一步该做什么。
  • 数字:我们需要进行运算的操作数据,一般就会跟在操作的运算指令后面。
  • 字符:我们字符都有对应的编码(比如ASCII码),字符也是按照0和1的方式存储在内存里面的,当我们需要输出字符串的时候,输出的指令后面就跟着若干个字符存储块。
  • 地址:如果我们想将结果输出到外部设备,比如显示器,打印机等,我们就需要这些设备的地址。

CPU常见指令集

RAM的data存储的一部分是指令集,这里列举一些常见的指令集。

  • LOAD: 从RAM中加载数据到CPU
  • ADD:计算2个数之和
  • STORE:将计算的数据写回RAM
  • COMPARE:比较2个数
  • JUMP IF Condition:判断条件,依据结果跳转RAM的另一个地址
  • JUMP:强制跳转RAM的另一个地址,类似于C语言中的jump指令
  • OUT:输出到一个外部设备地址,比如显示器
  • IN:从一个外部设备接收数据,比如键盘

还需要提一点,每个CPU中都有个以固定频率通断的电路,来同步所有的部件,这个部件叫做时钟。CPU的运算需要时钟不断震荡来同步所有的部件,让其协调完成任务(这个我也没太懂,可以这么理解:如果把CPU必做电脑的大脑,那么CPU的时钟就是CPU的心脏,想要运作其实都是心脏不断的跳动来保持你整个身体的运作的)。一个时钟周期CPU只能做一件事情,现代的cpu采用GHZ来表是计算速度,G代表十亿,HZ表示赫兹,代表每秒的次数。现代的cpu时钟每秒能通断数十亿次。所以现代的cpu的时钟频率及 电路通断次数可以达到数十亿词。这就让CPU可以极快的处理复杂任务。

取数据

CPU默认情况下都是顺序执行CPU中的指令的,只有在程序中需要跳转的时候才会地址跳跃访问。当计算机开始执行一个程序的时候,它会先向RAM发送一个地址以确定程序开始的位置。

image-20210824174603874.png

可以看到CPU通过地址总线发送一个地址为0110001的地址给RAM,RAM接受到信息后需要将数据返回给CPU。但是这个返回不是立即自动返回的,我们可以看到控制总线上有2条线: setenable。当着2条线没有通的时候,RAM并不会做任何的操作,即他接收到了CPU的地址请求,但是他并不会返回数据!只有当enable这个线路打开了之后,RAM才会将数据通过数据总线传输给CPU,这里返回的数据是0010001。

当CPU处理完了第一块数据之后,没有特殊的跳转情况,CPU就会顺序的请求下一个地址,后续的执行便是重复上述的步骤。

写数据

我们在执行程序过程中可能需要将计算的结果写入到RAM中,这时候先通过地址总线告诉RAM准备写入的地址,然后打开set线路,再通过数据总线将数据传输到RAM中。

image-20210821141505333.png

猜数游戏

我们通过一个猜数游戏来描述CPU的处理过程:游戏规则很简单,就是我们程序中随机出的一个值,然后依据用户键盘输出的数字,判断这个数字是否对的,如果是对的,就成功,不对就返回guess again。

首先,我们先可以从逻辑层面看看CPU的内部:

image-20210824211411237.png

其中参与核心工作的就两个部分:

控制单元

  • 就像队长一样,从RAM接受指令,然后解析这个指令为其他元件能够理解的命令。

ALU

  • 运算单元,用于执行所有的数学运算,比如加法,减法或者比较。
  • ALU有2个输入接口,我们将其标记为输入A和输入B。
  • ALU输出可能是一个比较结果,也可能是一个新的数,所以ALU会一个状态标志输出和一个OutPut输出

下图是执行该指令的线路图:

image-20210824221619085.png

  1. 首先,我们程序会运算出一个值,这个值是ALU先运算出来的,他会写到寄存器(1)上,这个写入的过程和RAM的过程一样,也要通过set和enable线路。ALU计算结果输出到寄存器的时候,寄存器只有在set通路的时候,才能存储该值。
  2. 我们set好了这个值到寄存器,这个只就是我们需要猜的数字,这个值需要被ALU再取出来然后和用户输入的值作比较。控制单元会打开enable线路,这时候寄存器(1)会连接到CPU的总线上去,总线上会有很多的(上面那4个寄存器)都带有独立enable和set线路的寄存器,这些寄存器可以用来存储之前运算结果的值。控制器会打开其中某个set线路,将值设置到该寄存器中,比如寄存器(2)。设置完成后,控制单元会断开enable线路从而清空整个CPU总线。(这个步骤就完成了将数字从一个寄存器传输到另一个寄存器,只需要通过enable和set开关,让线路连通即可)。
  3. 但是通过总线传输数据的缺点就是,一个时间点只能处理一个数字,那么ALU的2个输出就没办法同时获取到了,ALU所以添加了一个临时寄存器作为输入B,如寄存器(3)。该寄存器只是输出给ALU的,所以只有控制单元给其赋值的set线路。
  4. 而输出A的是上面那些寄存器和CPU总线直连的,所以当需要输入A的时候,只需要打开该寄存器上的enable线路。(这里视频中略过了获取用户输入的过程)
  5. 下面2个数都获取到了,我们需要从RAM读取下一个指令来判断如何处理者2个数,这个指令存储在指令寄存器中(4),指令寄存器只有set,因为他只存在输入到控制单元,而没有同步别人或者写回的操作。我们从指令解析出来了,需要ALU做什么操作传给ALU。
  6. ALU比较了数字后,因为是比较相等,所以结果是一个bool类型的值,ALU通过四根线来表示基表结果,4根线(主要其中的2根)的连通形式代表着A大,B大,一样大。这个Flag寄存器也是需要通过控制器set才能写入其中。
  7. 比较完成后,一般后面接着就是JUMP IF指令,用来一句判断进行跳转去执行不通的逻辑。CPU用一个指令地址寄存器来获取下一个指令在RAM的什么位置。当CPU准备好接受下一个指令的时候,将会将指令地址寄存器连接到CPU的bus上面(开启enable)。这个地址会最终流到RAM中,但是中间有一个内存地址寄存器作为中介来告诉RAM所需要数据的地址。 然后我们就可以打开控制总线的eanble线路,从RAM拿取下一个指令了。
  8. 我们拿到JUMP IF EQUAL指令后,控制单元会检查相等的标志线路是否被接通,该步骤是通过将指令寄存器和前面flag的相等结果,都连接到与门上,如果这2个条件都成立,那么与门的线路就是通路。这个线路会触发一个JUMP跳转,去从内存中获取下一块的数据,而那个数据是一块地址。这个地址会存如到指令地址寄存器中。
  9. 然后我们继续这个地址往下执行,这里如果猜对了,就会接受一个输出到显示器的指令,该指令后面就会接上你猜对了字符,并输出到显示器上,

我们将该逻辑块缩小,再对应上外围的布线,就能和上面主板做好对应得了。这样就很清楚总线和ALU及控制器,和外围的RAM及键盘显示器等设备如何进行交互的。

image-20210824213952193.png

参考资料

CPU的工作原理

文章分类
后端