几句话说清楚23:Skylake微架构(Microarchitecture)剖析(7)

接前Register Rename

这次得用Markdown画表格了,想来想去用markdown这么久还是第一次。

如前所述,physical register的数量远多于architectural register的数量。其实architectural register仅仅是一个“代号”,并不是真正存放数据的位置。用这种方式,可以消除WAWWAR这两种数据依赖进而增加程序整体的并行性。

那么到底怎么操作呢?其实本质上也就是建立一个“映射表”,一个从“代号”到存储位置的映射表。

E.g.

现有5个architectural register寄存器:r1, r2, r3, r4, r5;9个physical register寄存器:p1, p2, …, p9。

指令:

1
2
3
Add r1, r2, r3 ;r1 = r2 + r3
Sub r2, r1, r2 ;r2 = r1 - r2
Add r1, r4, r5 ;r1 = r4 + r5

最开始是一个简单的映射关系:

r1 r2 r3 r4 r5
p1 p2 p3 p4 p5

在这张表里面还有一个FreeList,用来保存还没有被占用的physical register

p6 p7 p8 p9

OK,首先考虑不使用Register Rename的情景。第二条指令是必须等待第一条指令执行完成之后才能执行,因为r1RAW型依赖。这个其实Register Rename也没有办法。但是第三条指令也不能在第二条指令之前执行,因为写入r1可能会影响第二条指令的结果(r2)。

为了增加指令的并行性,让第三条指令能与第一条指令并行,同时消除WAWWAR型依赖,看一下Register Rename是怎么做的。

第一条指令就用原始对应的寄存器,此时还没有Register Rename。对应的“映射表”Rename Table如下:

r1 p1
r2 p2
r3 p3
r4 p4
r5 p5

第二条指令中,r2针对第一条指令有WAR型依赖,可以将写入r2的结果放在另外一个寄存器里。从FreeList中选取下一个空闲的physical register,即p6

所以这条指令实际上就变成了Sub r6, r1, r2; r6 = r1 - r2

Rename Table如下:

r1 p1
r2 p6
r3 p3
r4 p4
r5 p5

即告之后续指令r2最终的结果保存在p6里面。

第三条指令,r1针对第一条指令有WAW型依赖,可以将写入r1的结果放到另外一个寄存器里。从FreeList中选取下一个空闲的physical register,即p7

所以这条指令实际上就变成了Add p7, p4, p5 ; p7 = p4 + p5

Rename Table如下:

r1 p7
r2 p6
r3 p3
r4 p4
r5 p5

即告之r1最终的结果保存在p7里面。

所有指令对architectural register的读取都先通过Rename Table获得确切地址。

回到最初提到的问题,因为第一条指令和第三条指令实际写入的寄存器(分别是p1和p7)并不冲突,且第二条指令仅在p1中读取数据,因此这两条指令可以并行执行。

现代CPU的Rename Table一般是在ROB里的RAT(Rename Alias Table)。同时physical register也会被ROB entry取代。

其实现在对Register Rename的理解更多的是建立一个概念,在整个微架构中,这一步不是一个孤立的组件,所有组件之间都需要紧密配合。

后续会对后端的执行进行示例介绍。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero