《超标量处理器设计》- 执行

《超标量处理器设计》- 执行

旁路网路

需要旁路网络的原因

比如两条指令RAW,最保守的方式是前面一条指令 FU 计算完成后,dst 写回了PRF,然后后面一条指令 是如此idx再去读PRF,费时,影响pipelie效率,所以需要旁路电路,从前一个指令计算出结果的时候,就fwd到新指令的入口。

简单设计的旁路网络


左边图没有旁路网络的时候,所有的寄存器的值从PRF来。右边那个比如FU0的值可以从PRF来,也可以从上一次FU0自己算出来的值来,还可以从FU1的计算的结果来。

旁路电路冲突的解决
  • 产生conflict的原因
    如下图,如果一个FU中有几个计算模块,比如第一个FU,可以同时执行Add和shift,add latency=2,shift latency=1,则下下张图的时序,有可能出现add和shift的运算同时算出来,都需要fwd(forward),这就出现了旁路电路fwd的冲突

  • 解决旁路电路conflict方式
    根据是否进行推测,有两种方案(前提:我们知道指令的执行latency)
    推测:假设所有的都不会出现conflict,当要开始执行的时候,再检查是否会和同FU的其他指令产生conflitc,如果产生conflict就放回issue queue.
    不推测:在选择指令的时候,就算好,如果会和前面的指令发生conflict,这个周期就不把指令送到FU

复杂设计的旁路网络

复杂电路引起增加流水级数

在现实的处理器里,FU比较多,布线复杂,从PRF读的数据需要很长的传输才能到达FU的数据端,而且数据来源不止从PRF来,有可能还要做mux,所以把这个阶段单拿一个周期,叫source drive。如果没有这个阶段,复杂的准备工作和冒险处理将和执行阶段抢时间,导致cycle拉长。
同理,计算的数据到写入PRF也要很长的时间,所以单拎出来一个周期 result drive

增加流水级数引起旁路电路的复杂度快速提升


指令在result drive和write back阶段可以发起forward,在source drive阶段和execute阶段可以接收forward,导致forward的组合急剧增多

简化旁路电路采取的方式(cluster)
  • cluster bypass
    把不同的FU放在不同的cluster中(一个cluster放>=1)FU,同cluster内的FU之间可以快速forward,没有source drive和result drive的环节,不同的cluster之间数据如果有依赖,只能通过读取PRF的方式获取

存储器指令的加速

影响存储指令速度的原因

1. load/store指令之间也会出现和寄存器类似的WAW/WAR/RAW hazard
解决hazard的方式
  • 完全顺序执行
    缺点:存储的速度慢;优点:可靠

  • 部分乱序执行
    store和store之间保持顺序,两个store之间的load可以乱序
    当指令A被select的时候,就可以wake up 指令B/C/D,当B/C/D的地址算出来的时候,A的已经算出来了,因此B/C/D 可以和A比较是否发生地址冲突,如果不发生,load就可以发出去,如果发生,load就可以等到store的回来直接用store的数据。
    指令B/C/D并不阻塞下一条store 指令E,因为对于AXI来说是不同的channel,而且即使指令A没有AXI的bresp回来,指令E也可以发出去,但是指令F/G检查冲突的时候要不仅要和指令E做地址比较,也要和指令A做地址比较。
    那么哪些load指令需要和前一个store做比较,哪些需要和前前…个store指令做比较,这就需要记录load和store 之间的顺序,可以用ROB来做辅助标记。所有的store的指令相关的数据都放在store buffer里,如果load有匹配的上的,就去store buffer取数据,就不向AXI去read了。

  • 完全乱序执行
    只要load的操作数准备好了,就发送

2.数据放在不同层级cache中,取数据慢

解决方式:D-cache缺失的时候,处理器继续执行后面的load/store,使用非阻塞的fetch方式

3.一次取的cacheline数据多,采用关键字优先来解决
4.通过提前触发预取