超标量处理器的唤醒

唤醒是指被仲裁电路选中的指令将其目的寄存器的编号(简称为dst_tag)和发射队列中所有的源寄存器的编号进行比较,并将那些比较结果相等的源寄存器进行标记的过程(标记为ready状态)。

单周期指令的唤醒

  • 因为要将被选中指令的目的寄存器的编号送到发射队列当中的所有的地方,当发射队列的容量比较大或者个数比较多时,这个目的寄存器的编号就需要走很长的路。
  • 每个仲裁电路都会送出这样一个编号值,发射队列中的每个源寄存器都会和所有仲裁电路送出的编号值进行比较
  • 一般情况下,仲裁电路的个数等于issue width的值。
  • 如下例举了一个4 issue的例子:
    • 超标量处理器的唤醒_第1张图片
    • 假设4个选择电路共用一个issue queue;
    • (这个图是针对单周期指令来说的,这样在select阶段选中的当拍,就可以对issue queue中的其他指令进行唤醒)
    • 这样发射队列当中的每个表项都需要向四个仲裁电路发出请求信号(在图8.33中称为Request),
    • 同时也会从四个仲裁电路收到四个响应信号(在图8.33中称为Grant)。
    • 当然这四个响应信号中,只有其中的一个是有效的,这个有效的响应信号会将这条指令的目的寄存器编号送到指定的总线上(在图8.33中称为tag bus)。
    • 上述每个entry中的内容不做赘述,只需要关注issued:
      • issued, 一条指令被仲裁电路选中后,可能不会马上离开发射队列(load指令),因此需要将它进行标记,这样的指令将不会向仲裁电路发出请求信号。

多周期指令的唤醒 

  • 当一条指令无法在一个周期之内执行完毕时,就不能在被仲裁电路选中的当前周期对发射队列中其他的指令进行唤醒,而需要根据它在FU中执行的周期数,将这个唤醒过程进行延迟。
  • 唤醒主要分为两个阶段:
    • 第一阶段是将被选中指令的目的寄存器的编号值送到总线上,
    • 第二阶段是将总线上的值和发射队列中所有源寄存器的编号进行比较
  • 因此要将唤醒过程进行延迟,也就是将这两个阶段进行延迟,这也就产生了两种方法,
    • 一种称为延迟广播(delayed tag broadcast),
    • 另一种称为延迟唤醒(delayed wake-up)。
  • 延迟广播:
    • 如果发现被仲裁电路选中的指令执行周期大于1,则在选中的当前周期,并不将这条指令的目的寄存器的编号送到总线上。
    • 而是根据这条被选中指令所需要执行的周期数(假设执行周期为N),延迟N-1个周期之后,才将它送到总线上,如图8.34所示。超标量处理器的唤醒_第2张图片
    • 这种方式可能会产生冲突:即delay的broadcast和当拍的broadcast撞车了;超标量处理器的唤醒_第3张图片
      • 解决方式:
        • 增加tag bus的个数,此举会增加唤醒电路的复杂度;
        • 记录当前在FU中执行的指令的周期数,如果发现后续进来的指令,与这个记录的周期数冲突,则不要仲裁该指令;超标量处理器的唤醒_第4张图片
        • 这种方式有一个缺点:
          • 访问表格和select电路是并行的,如果当拍被否决了,则当拍不能选择其他的指令,但是实际上本周期,指令C是可以select出去的;
          • 解决方式是可以先查询表格,如果否决了,则不要向select电路发起请求,这样可以将机会留给他人;
          • 这种相当于串行的访问表格和select电路,会增大延迟;
    • 延迟广播,是对唤醒的第一阶段进行延迟,延迟唤醒则是对第二个阶段进行延迟;
  • 延迟唤醒

         超标量处理器的唤醒_第5张图片

  • 被仲裁电路选中的指令会按照正常的流程,在当前周期就将它的目的寄存器编号送到对应的总线上,并和发射队列(Issue Queue)中所有的源寄存器进行比较。
  • 但是,此时比较结果相等的寄存器并不一定马上被置为准备好的状态(也就是ready状态),而是根据这条进行广播的指令所需要的执行周期数,进行相应周期的延迟,然后再改变发射队列中源寄存器的状态,这就相当于延迟进行了唤醒。  超标量处理器的唤醒_第6张图片
  • 实现方式:
    • 本质就是要在发射队列(Issue Queue)中,每条指令对应的ready状态位之前加入延迟功能的寄存器。
    • 此处提供一种实现方式:超标量处理器的唤醒_第7张图片
      • decode阶段,将这条指令需要执行的周期数,一并写入issue queue;
      • 当一条指令被仲裁电路选中之后,除了将它的目的寄存器的编号送到总线之外,还需要将它的DELAY值也一并送到总线上,称这个总线为DELAY bus。
      • 一般来说,每个FU都会对应一个DELAY bus,根据寄存器编号的比较结果,将对应DELAY bus的值“捕捉”到发射队列相应的表项(entry)中
      • 然后再将这个DELAY值进行移位的处理,完成延迟唤醒的过程。
      • 此处issued queue的entry内容如下:
        • Freed:         
          • 指令写入后,不再空闲;
          • inst被select电路选中,并且确定没有问题时,离开issue queue;
          • 没有问题指的是,某条指令被select电路选中,不一定保证这个指令就一定能拿到操作数,因为如前所述,load指令是推测唤醒的,有可能会miss, 如果miss了,需要再次进行仲裁;
        • issued:表示已经被select电路选中;被选中的inst可能不会马上离开,所以加以标记,不要向仲裁电路发请求;
        • SrcL_M: matched的意思,select 电路grnt时,清零;比较相等时,置1;
        • SrcL_shift: 寄存器标号比较结果相等时,将delay写入该位置;该位置每周期右移一位,用来体现是否已经ready;
        • rdy: 就是SrcL_shift的计算结果;
        • DELAY: 用来记录每条指令在FU的执行周期数;
        • ROB idx: 指令的年龄信息;

你可能感兴趣的:(risc-v,risc-v)