其他问题多周期指令我们之前设计的处理器指令集中的所有指令都包括一些简单的操作,例如数字加法。这些操作可以在执行阶段中一个周期内处理完。
在一个更完整的指令集中,还有整数乘法除法、以及浮点运算。在我们之前设计的流水化处理器中,浮点加法需要3、4个周期,整数除法需要32个周期。
实现多周期指令的一种简单方法就是简单地扩展执行阶段逻辑的功能,添加一些整数和浮点算数运算单元。一条指令在执行阶段中逗留它所需要的多个时钟周期,会导致取指和译码阶段暂停。这种方法实现起来很简单,但是得到的性能并不是太好。
通过采用独立于主流水线的特殊硬件功能单元来处理较为复杂的操作,可以得到更好的性能。通常,有一个功能单元来执行整数乘法和除法,还有一个来执行浮点操作(协处理器)。
当一条指令进入到译码阶段时,它可以被发射到特殊单元。在这个特殊单元执行该操作时,流水线会继续处理其他指令。通常,浮点单元本身也是流水线化的,因此多条指令可以在主流水线和各个单元中并行执行。
不同单元的操作必须同步,以避免出错。
如果在不同单元执行的各个指令之间有数据相关,控制逻辑可能需要暂停系统的某个部分,直到由系统其他部分处理的操作的结果完成。
使用各种形式的转发,将结果从系统的一部分传递到其他部分,这和前面的PIPE流水线各个阶段之间的转发一样。虽然与PIPE相比,整个设计变得更复杂,但还是可以使用暂停、转发、以及流水线控制等同样的技术,使整体行为与顺序的ISA模型相匹配。
与存储系统的接口在我们之前的流水化CPU中,我们假设取指单元和数据存储器都可以在一个时钟周期内读或是写存储器中任意的位置。
但是,实际情况是,我们以存储器位置的虚拟地址来引用数据,这就要求在执行实际的读写操作之前,要将虚拟地址翻译成物理地址。显然,要在一个时钟周期内完成所有这些处理是不现实的。更糟糕的是,要访问的存储器的的值可能位于磁盘上,这会需要上百万个时钟周期才能把数据读入到处理器存储器中。
存储系统:CPU的存储系统是由多种硬件存储器和管理虚拟存储器的操作系统软件共同组成的。
存储系统被组织成一个层次结构,较快但是较小的存储器保持着存储器的一个子集,而较慢但是较大的存储器作为它的后备。
最靠近处理器的一层是高速缓存(cache)存储器,它提供对最常使用的存储器位置的快速访问。一般有2个一层cache——一个用于读指令,一个用于读写数据。
还有另一种类型的高速缓存存储器,称为TLB(Translation Look-aside Buffer翻译后备缓冲器),它提供了从虚拟地址到物理地址的快速翻译。
将TLB和cache结合起来使用,在大多数时候,确实可能在一个时钟周期内读指令并读或是写数据。
缓存不命中:有些引用的位置不在高速缓存中,即出现高速缓存不命中。在最好的情况下,可以冲=从较高层的cache或处理器的主存中找到不命中的数据,这需要3--20个时钟周期。同时,流水线会简单地暂停,将指令保持在取值或访存阶段,直到高速缓存能够执行读或写操作。
缺页异常:当被引用的存储器位置实际上是在磁盘存储器上的,硬件会产生一个缺页异常信号。同其他异常一样,这个异常会导致处理器调用操作系统的异常处理程序代码。然后这段代码会发起一个从磁盘到主存的传送操作。
让硬件调用操作系统例程,然后操作系统例程又会将控制返回给硬件,这就使得硬件和系统软件在处理缺页时能协同工作。
从处理器的角度来看,将用暂停来处理短时间的高速缓存不命中和用异常处理来处理长时间的缺页结合起来,能够顾及到存储器访问时由于存储器层次结构引起的所有不可预测性。 |