在超标量处理器内部有两个状态,
- Architecture State
- 指令集定义的状态,例如通用寄存器的值、PC值以及存储器的值等;
- Speculative State
- 超标量处理器内部的状态,例如重命名使用的物理寄存器、重排序缓存(ROB)、发射队列(Issue Queue)和Store Buffer等部件中的值,这些状态是处理器在运行的过程中产生的
- 由于乱序执行的原因,它总是超前于指令集定义的状态;
- 当然,这些状态也可能有一些是不正确的,但是处理器的硬件会将其内部解决掉,不会让外界看到这些不正确的状态。
- 一条指令只有退休(retire)的时候才会更新处理器中指令集定义的状态,就好像处理器在按照串行的顺序执行程序一样,在此之前,指令只能改变处理器内部的状态
- 只有一条指令满足退休的条件:变为ROB中最旧的指令、已经处于complete状态,并且没有异常发生,这才能够将这条指令对应的处理器内部状态更新到指令集定义的状态中。
- 在超标量处理器内部包括了很多的部件,但是许多部件都不应该被外界看到,它们都是为乱序执行的特征而服务的 ;
- 概括起来就是,除了指令集中定义的资源,例如PC寄存器、存储器或者通用寄存器等部件之外,其他的资源都属于处理器内部的状态;
- 在超标量处理器中,根据架构的不同,会对应着不同的方法来管理指令集定义的状态,本节介绍两种主要的方法。
- (1)使用 ROB 管理指令集定义的状态,被Intel P6架构、Intel Core架构等使用。
- (2)使用物理寄存器管理指令集定义的状态,被Intel Pentium 4、Alpha 21264 和 MIPS R10000 等处理器使用。
- 主要看下第二种方式;
使用物理寄存器管理指令集定义的状态
- 这种方式使用一个统一的物理寄存器堆(PRF),指令集中定义的所有逻辑寄存器都混在这个寄存器堆中
- 当然,为了进行寄存器重命名,在它当中包含了更多的寄存器,当一条指令被寄存器重命名之后,它的目的寄存器就和一个物理寄存器产生了对应关系,不过,这个关系此时并不能被外界看到,它只是处理器内部的状态。
- 当这条指令的结果被计算出来的时候,这条指令的状态变为了complete,当然,此时它仍然属于处理器内部的状态;
- 等到一条指令退休(retire)的时候,这条指令的结果仍然会占据着原来对应的物理寄存器,只不过此时它的状态会被标记为 Architecture state
- 等到后续有另外一条指令也写到同一个目的寄存器,并且这条后续的指令退休的时候,才可以将当前的这条指令对应的物理寄存器进行释放。
- 这种方式相当于将指令集定义中的逻辑寄存器融入到了物理寄存器中,比较来说,相对于基于ROB的管理方式,这种方式的优点有如下三个。
- (1)当指令从 ROB中退休的时候,不需要将指令的结果进行搬移,它仍旧会存在于物理寄存器中,也就是说,一旦指令的源操作数被确定存在于哪里,以后就不会再变化了,这样便于处理器实现低功耗的设计。
- (2)在基于ROB进行状态管理的方式中,需要从ROB中开辟空间来存放指令的结果,但是在程序中,有相当一部分的指令并没有目的寄存器,例如store指令、比较指令和分支指令,因此ROB中会有一部分的空间是浪费的,而使用物理寄存器进行状态管理的方式就可以避免这样的问题,这种方式只会对存在目的寄存器的指令分配空间,其他不存在目的寄存器的指令,不会对应到任何物理寄存器。因此使用这种方式,占用的物理寄存器的个数小于此时 ROB 中的指令个数。
- (3) ROB是一个集中的管理方式,所有指令都需要从其中读取操作数,同时所有的指令也需要将结果写到其中,再加上对ROB空间的占用和回收都需要读写端口的支持,因此这需要大量的读写端口,会使ROB变得非常臃肿,严重拖累处理器的速度,而反观使用物理寄存器进行状态管理的方式,可以采用一些灵活的方式来避免多端口的负面影响,例如对物理寄存器堆(PRF)采用Cluster结构,这样可以提高处理器的速度。
- 也有如下的缺点:
- 造成寄存器重命名的过程比较复杂,用物理寄存器进行状态管理的方式中,需要一个额外的表格来存放哪些物理寄存器是空闲的,并且重命名映射关系的建立和释放过程都会比较复杂。
- 当处理器外部需要访问指令集中定义的寄存器时,由于这些寄存器是混在物理寄存器当中、无法直接进行分辨的,因此需要一个额外的表格来存放哪些物理寄存器是Architecture state,所有的这些功能在一定程度上都影响了处理器的速度。