You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
9.8 KiB
Markdown

2 years ago
# 17 | 建立数据通路(上):指令+运算=CPU
前面几讲里我从两个不同的部分为你讲解了CPU的功能。
在“**指令**”部分,我为你讲解了计算机的“指令”是怎么运行的,也就是我们撰写的代码,是怎么变成一条条的机器能够理解的指令的,以及是按照什么样的顺序运行的。
在“**计算**”部分,我为你讲解了计算机的“计算”部分是怎么执行的,数据的二进制表示是怎么样的,我们执行的加法和乘法又是通过什么样的电路来实现的。
然而光知道这两部分还不能算是真正揭开了CPU的秘密只有把“指令”和“计算”这两部分功能连通起来我们才能构成一个真正完整的CPU。这一讲我们就在前面知识的基础上来看一个完整的CPU是怎么运转起来的。
## 指令周期Instruction Cycle
前面讲计算机机器码的时候我向你介绍过PC寄存器、指令寄存器还介绍过MIPS体系结构的计算机所用到的R、I、J类指令。如果我们仔细看一看可以发现计算机每执行一条指令的过程可以分解成这样几个步骤。
1.**Fetch****取得指令**也就是从PC寄存器里找到对应的指令地址根据指令地址从内存里把具体的指令加载到指令寄存器中然后把PC寄存器自增好在未来执行下一条指令。
2.**Decode****指令译码**也就是根据指令寄存器里面的指令解析成要进行什么样的操作是R、I、J中的哪一种指令具体要操作哪些寄存器、数据或者内存地址。
3.**Execute****执行指令**也就是实际运行对应的R、I、J这些特定的指令进行算术逻辑操作、数据传输或者直接的地址跳转。
4.重复进行13的步骤。
这样的步骤,其实就是一个永不停歇的“**Fetch - Decode - Execute**”的循环,我们把这个循环称之为**指令周期**Instruction Cycle
![](https://static001.geekbang.org/resource/image/18/a7/1840bead02cfbe5d8f70e2f0a7b962a7.jpg)
指令周期Instruction Cycle
在这个循环过程中,不同部分其实是由计算机中的不同组件完成的。不知道你还记不记得,我们在专栏一开始讲的计算机组成的五大组件?
在取指令的阶段,我们的指令是放在**存储器**里的实际上通过PC寄存器和指令寄存器取出指令的过程是由**控制器**Control Unit操作的。指令的解码过程也是由**控制器**进行的。一旦到了执行指令阶段无论是进行算术操作、逻辑操作的R型指令还是进行数据传输、条件分支的I型指令都是由**算术逻辑单元**ALU操作的也就是由**运算器**处理的。不过,如果是一个简单的无条件地址跳转,那么我们可以直接在**控制器**里面完成,不需要用到运算器。
![](https://static001.geekbang.org/resource/image/bd/67/bde3548a4789ba49cab74c8c1ab02a67.jpeg)
不同步骤在不同组件之内完成
除了Instruction Cycle这个指令周期在CPU里面我们还会提到另外两个常见的Cycle。一个叫**Machine Cycle****机器周期**或者**CPU周期**。CPU内部的操作速度很快但是访问内存的速度却要慢很多。每一条指令都需要从内存里面加载而来所以我们一般把从内存里面读取一条指令的最短时间称为CPU周期。
还有一个是我们之前提过的**Clock Cycle**,也就是**时钟周期**以及我们机器的主频。一个CPU周期通常会由几个时钟周期累积起来。一个CPU周期的时间就是这几个Clock Cycle的总和。
对于一个指令周期来说我们取出一条指令然后执行它至少需要两个CPU周期。取出指令至少需要一个CPU周期执行至少也需要一个CPU周期复杂的指令则需要更多的CPU周期。
![](https://static001.geekbang.org/resource/image/1a/48/1a7d2d6cf7cb78a8f48775268f452e48.jpeg)
三个周期Cycle之间的关系
所以我们说一个指令周期包含多个CPU周期而一个CPU周期包含多个时钟周期。
## 建立数据通路
在专栏一开始不少同学留言问到ALU就是运算器吗在讨论计算机五大组件的运算器的时候我们提到过好几个不同的相关名词比如ALU、运算器、处理器单元、数据通路它们之间到底是什么关系呢
名字是什么其实并不重要,一般来说,我们可以认为,数据通路就是我们的处理器单元。它通常由两类原件组成。
第一类叫**操作元件**也叫组合逻辑元件Combinational Element其实就是我们的ALU。在前面讲ALU的过程中可以看到它们的功能就是在特定的输入下根据下面的组合电路的逻辑生成特定的输出。
第二类叫**存储元件**也有叫状态元件State Element的。比如我们在计算过程中需要用到的寄存器无论是通用寄存器还是状态寄存器其实都是存储元件。
我们通过数据总线的方式,把它们连接起来,就可以完成数据的存储、处理和传输了,这就是所谓的**建立数据通路**了。
下面我们来说**控制器**。它的逻辑就没那么复杂了。我们可以把它看成只是机械地重复“Fetch - Decode - Execute“循环中的前两个步骤然后把最后一个步骤通过控制器产生的控制信号交给ALU去处理。
听起来是不是很简单?实际上,控制器的电路特别复杂。下面我给你详细解析一下。
一方面所有CPU支持的指令都会在控制器里面被解析成不同的输出信号。我们之前说过现在的Intel CPU支持2000个以上的指令。这意味着控制器输出的控制信号至少有2000种不同的组合。
运算器里的ALU和各种组合逻辑电路可以认为是一个固定功能的电路。控制器“翻译”出来的就是不同的控制信号。这些控制信号告诉ALU去做不同的计算。可以说正是控制器的存在让我们可以“编程”来实现功能能让我们的“存储程序型计算机”名副其实。
![](https://static001.geekbang.org/resource/image/46/6f/46087a894b4ac182fab83ac3786cad6f.jpeg)
指令译码器将输入的机器码解析成不同的操作码和操作数然后传输给ALU进行计算
## CPU所需要的硬件电路
那么要想搭建出来整个CPU我们需要在数字电路层面实现这样一些功能。
首先自然是我们之前已经讲解过的ALU了它实际就是一个没有状态的根据输入计算输出结果的第一个电路。
第二我们需要有一个能够进行状态读写的电路元件也就是我们的寄存器。我们需要有一个电路能够存储到上一次的计算结果。这个计算结果并不一定要立刻拿到电路的下游去使用但是可以在需要的时候拿出来用。常见的能够进行状态读写的电路就有锁存器Latch以及我们后面要讲的D触发器Data/Delay Flip-flop的电路。
第三我们需要有一个“自动”的电路按照固定的周期不停地实现PC寄存器自增自动地去执行“Fetch - Decode - Execute“的步骤。我们的程序执行并不是靠人去拨动开关来执行指令的。我们希望有一个“自动”的电路不停地去一条条执行指令。
我们看似写了各种复杂的高级程序进行各种函数调用、条件跳转。其实只是修改PC寄存器里面的地址。PC寄存器里面的地址一修改计算机就可以加载一条指令新指令往下运行。实际上PC寄存器还有一个名字就叫作程序计数器。顾名思义就是随着时间变化不断去数数。数的数字变大了就去执行一条新指令。所以我们需要的就是一个自动数数的电路。
第四我们需要有一个“译码”的电路。无论是对于指令进行decode还是对于拿到的内存地址去获取对应的数据或者指令我们都需要通过一个电路找到对应的数据。这个对应的自然就是“译码器”的电路了。
好了现在我们把这四类电路通过各种方式组合在一起就能最终组成功能强大的CPU了。但是要实现这四种电路中的中间两种我们还需要时钟电路的配合。下一节我们一起来看一看这些基础的电路功能是怎么实现的以及怎么把这些电路组合起来变成一个CPU。
## 总结延伸
好了到这里我们已经把CPU运转需要的数据通路和控制器介绍完了也找出了需要完成这些功能需要的4种基本电路。它们分别是ALU这样的组合逻辑电路、用来存储数据的锁存器和D触发器电路、用来实现PC寄存器的计数器电路以及用来解码和寻址的译码器电路。
虽然CPU已经是由几十亿个晶体管组成的及其复杂的电路但是它仍然是由这样一个个基本功能的电路组成的。只要搞清楚这些电路的运作原理你自然也就弄明白了CPU的工作原理。
## 推荐阅读
如果想要了解数据通路,可以参看《计算机组成与设计 硬件软件接口》的第5版的4.1到4.4节。专栏里的内容是从更高一层的抽象逻辑来解释这些问题,而教科书里包含了更多电路的技术细节。这两者结合起来学习,能够帮助你更深入地去理解数据通路。
## 课后思考
这一讲我们说CPU好像一个永不停歇的机器一直在不停地读取下一条指令去运行。那为什么CPU还会有满载运行和Idle闲置的状态呢请你自己搜索研究一下这是为什么并在留言区写下你的思考和答案。
欢迎你留言和我分享,你也可以把今天的文章分享给你的朋友,和他一起学习和进步。