27 lines
5.4 KiB
Markdown
27 lines
5.4 KiB
Markdown
计组第二章知识脉络
|
||
================
|
||
|
||
本章讨论控制器的设计。在第一章的基础上,我们已经成功完成了数据通路的设计,这意味着计算机已经具有了[计算]的硬件条件,这就好比工厂已经有了工人,但是这还远远不够。为了让计算机运行起来,还需要正确地指导“工人”,使他们协同完成一系列用户指定的工作,这就是控制器的任务。这里,用户是通过`指令`的形式,来传达工作的要求,控制器的设计就需要识别这些指令,根据指令的内容控制数据通路的运行。
|
||
|
||
所以本章主要讨论两个问题,即指令以及指令的实现方式,具体又分为`单周期CPU`,`多周期CPU`以及`流水线`。
|
||
|
||
指令部分首先要关注的点是指令的设计,即如何合理组织`操作码`(opcode),使它代表不同长度的各种指令,本质上就是一个编码的问题。此外要了解具体的`MIPS`指令集的三种指令类型,即`R`型,`I`型,`J`型指令,它们各自的格式,以及实例。还需要关注一个`寻址方式`的问题。
|
||
|
||
不同的指令执行的步骤也不相同,不过大体上还是存在一些共性,比如都存在`取指`(Instruction Fetch),`指令译码`(Instruction Decode)操作。可以将`MIPS`指令集的指令都划分为五个基本操作,除了上面两个以外,还有`指令执行EXE`,`存储器读写MEM`,以及`结果写回`(Write Back)。在此基础上,可以给出`单周期CPU`的设计方案,即每条指令都执行一个时钟周期(`CPI = 1`),时钟周期与执行时间最长的指令一直,并且将一个时钟周期划分为上述五个子段,分别执行相应的功能。控制信号在`指令译码`阶段全部给出,并且在整个时钟周期内保持。`单周期CPU`控制器的设计方案如下图所示:
|
||
|
||

|
||
|
||
这张图肯定是要非常熟悉的,其中的各个控制信号都要清楚,以及在每条指令执行的时候,各个控制信号的值是多少。
|
||
|
||
在指令集比较大的时候,`单周期CPU`的效率会比较低下,这是因为此时不同指令执行所需要的时间往往有很大差异,在`单周期CPU`中,所有指令的执行时间都与最长的指令相同。为了解决这个问题,产生了`多周期CPU`的设计方案,即指令的每一个阶段都执行一个时钟周期,不同的指令具有不同的时钟周期数,例如`jump`指令只需要两个时钟周期,而`lw`执行需要五个时钟周期。
|
||
|
||
容易看到,`多周期CPU`设计的难点在于一个时序的问题,即在指令执行的不同周期内,需要给到数据通路不同的控制信号。这里有两种实现方法,一种是`硬布线控制器`,它是通过引入一个`节拍发生器`来指示当前指令执行到了哪一个阶段,所以控制信号是`操作码`和`节拍`的函数,通过复杂的组合逻辑电路来实现。另一种方案是`微程序控制器`,它是将控制信号全部存储在`控制存储器`当中,通过`微指令`和`下地址逻辑`来给出当前阶段的控制信号。需要关注一下`多周期CPU`的各条执行的`有限状态机`。
|
||
|
||
实际上,无论是`单周期CPU`还是`多周期CPU`,它们的元件利用率都还有很大的提升余地,一个洗衣房的例子可以很好地说明`流水线`的优势,`流水线`的本质是`时间并行`,而非`空间并行`,后者是指同时存在多套硬件系统并行运行。`流水线`将一个指令的执行过程划分为若干个`流水级`(piped stages),流水级的长度需要与最耗时的操作一致,在这个方面`流水线`是类似于`多周期CPU`的,即每一条执行的执行都需要多个周期;但是为了避免`结构冲突`,不同的指令的流水级数仍然是相同的,这个方面`流水线`类似于`单周期CPU`。`流水线`实现的难点在于任一时刻,数据通路的不同部件是在执行不同的指令,因此需要给到不同执令的控制信号,因此需要设置`流水线寄存器`来传递这些控制信号,除此以外还要传递各条执行的参数,目标操作数,中间结果等。`流水线`实现的关键就在于`流水线寄存器`。
|
||
|
||
然而,`流水线`还存在一些问题,即它的执行过程中会产生一些`冲突`,或者`冒险`(hazard)。具体说来,有三种冲突,即`结构冲突`,`数据冲突`以及`控制冲突`。`结构冲突`是指不同指令对同一资源的抢占,比如在`取指阶段`以及`MEM`阶段都可能发生内存的访问,解决方案是`暂停流水线`,或者增设资源,比如这里分别设置执令存储器与数据存储器,或者使存储器具有两个读取端口;
|
||
|
||
`数据冲突`是指相邻执行的指令中,对数据的依赖性关系,具有`RAW`,`WAW`,`WAR`三种情形,其中在`MIPS`中只可能出现`RAW`。数据冲突的解决方案有`数据旁路`,`暂停流水线`,`编译器静态调度`或者`动态调度`,需要指出前一条指令是`lw`时的`数据冲突`无法通过`旁路`来解决,而必须进行`阻塞`。
|
||
|
||
`控制冲突`是跳转相关执行会出现的,控制器由于不知道下一条指令的地址,所以无法实现指令预取。`控制冲突`的解决方案有`暂停流水线`,`静态预测`,`动态预测`,`延迟槽`,其中`动态预测`还可以通过采取两位预测位的方法,对于多重循环获得更高的预测精度。
|