Skip to content

重命名 Rename

在乱序处理器中,重命名阶段负责管理和维护逻辑寄存器与物理寄存器之间的映射,通过对逻辑寄存器的重命名,实现指令间依赖的消除,并完成乱序调度。本节介绍的重命名主要包含 Rename, RenameTable, FreeList 三个模块,分别负责 Rename 流水级的控制、重命名表的维护和空闲寄存器的维护。

重命名表 RenameTable

重命名表的作用是维护逻辑寄存器与物理寄存器之间的映射关系,其操作端口包括一组读口 readPorts 和一组写口 specWritePorts。重命名表内部包含 32 个物理寄存器堆地址宽度的寄存器,分别代表 32 个逻辑寄存器对应的物理寄存器地址。目前,定点和浮点寄存器堆各有一套重命名表,根据未来的指令扩展情况,重命名表可以被配置成记录更多的内容(如条件寄存器堆、向量寄存器堆等重命名状态)。

readPorts 是一组同步读接口,在 T+1 周期根据 T 周期的读地址和 hold 信号,对应地输出相应的重命名表读数据。在使用这一组端口时,读地址会在译码阶段进行赋值,并根据相应流水级的阻塞情况,对 hold 进行赋值。如果 hold 为 1,则读数据会保持不变,否则读数据将根据最新的读地址而更新。

specWritePorts 是一组写接口,根据重命名或者 ROB 回滚的状态,分别依据新指令重命名的信息和 ROB 回滚的信息,完成对重命名表的更新。T 周期的写数据会被更新至 T+1 周期的读数据中。

代码中的 archWritePortsdebug_rdata 两组端口仅用于调试使用,用来为 DiffTest 框架提供寄存器信息。

空闲寄存器列表 FreeList

FreeList 记录了所有的空闲寄存器状态,其大小是可以通过类参数 size 配置的。FreeList 本质上是一个队列,由入队指针、出队指针和队列存储组成。

初始化时,FreeList 中包含所有可用的物理寄存器。在我们的设计中,初始时逻辑寄存器 i 会被映射至物理寄存器 i,因此 FreeList 在初始状态下包含 32-191 共 160 个空闲物理寄存器号。重命名时,FreeList 会给出至多 RenameWidth 个空闲物理寄存器号供使用。物理寄存器被释放时(ROB 提交指令或者回滚),FreeList 每一拍至多可以进入 CommitWidth 个空闲物理寄存器号。

在香山处理器的设计中,针对定点物理寄存器支持多次引用,并通过引用计数表(RefTable)记录每一个物理寄存器被引用的次数。通过引用计数,香山支持将多个逻辑寄存器映射至同一个物理寄存器,并支持对 Move 指令的消除优化(Move Elimination)。在这种情况下,空闲的物理寄存器数量理论上最高可达到物理寄存器总数 - 1。因此,在香山处理器中,定点 FreeList 大小与物理寄存器堆大小相同(默认为 192),浮点 FreeList 大小是物理寄存器堆数量 - 32(默认为 160)。

目前,FreeList 在香山中共有两种实现,分别在不存在 / 存在引用计数功能的情况下使用,对应 StdFreeListMEFreeList。对于不存在引用计数的情况,当发生 ROB 回滚时,FreeList 中释放的空闲寄存器一定是前面恰好被分配出的那一些,且与回滚指令中需要分配新物理寄存器的数量相同。在种情况下,FreeList 的存储不需要被重复写入,只需要将出队指针往前回滚即可。对于存在引用计数的情况,由于重复引用情况的存在(不需要通过 FreeList 分配,而是增加一个物理寄存器的引用计数),回滚的物理寄存器数量与 FreeList 的释放数量并不一定相同。在这种情况下,FreeList 需要维护几个写端口,方便通过引用计数机制来维护实际释放的物理寄存器。

引用计数表 RefTable

如前所述,引用计数表的作用是记录每一个物理寄存器被引用的次数,具有分配 allocate(增加引用次数)、取消分配 deallocate(减少引用次数)、释放物理寄存器(至 FreeList)freeRegs 三组模块接口。

在存在引用计数功能的情况下,重命名对每一个物理寄存器的分配与释放都会告知 RefCounter。当一个物理寄存器的引用计数值变成 0 时,对应的物理寄存器会被释放进 FreeList 等待下次分配。为了时序的考虑,物理寄存器的释放会延后两拍进行。

Rename

重命名流水级的主要作用是更新指令的物理寄存器信息,包括 psrc, pdestold_pdestpsrcold_pdest 一般来源于重命名表。当一条指令需要分配新的物理寄存器时,如定点指令需要写寄存器堆且目的寄存器非零号寄存器、浮点指令需要写寄存器堆时,pdest 来源于 FreeList 的分配结果。由于指令间依赖的存在,对于同一拍进行重命名的指令,Rename 模块需要负责在他们之间进行物理寄存器号的旁路,如当指令 1 需要使用指令 0 的结果时,指令 1 的对应源操作数需要来源于指令 1 的目的寄存器。

香山处理器实现了 Move 指令消除(Move Elimination)功能,在这种情况下,对 Move 指令不再分配新的物理寄存器,而是直接将其目的逻辑寄存器重命名至源操作数对应的物理寄存器。

香山处理器还实现了对于 LUI 和 LOAD 指令对的操作数旁路功能,在这种情况下,LOAD 指令的基地址将被替换为立即数(而不是 LUI 的目的寄存器),替换是通过对 srcType 的修改完成的,立即数会被存入 psrc 和 imm 域中。

在目前的实现中,为了时序的考虑,我们做了如下优化:在需要资源分配与仲裁的位置大多采用了保守策略,如浮点物理寄存器无空闲时,我们也将阻塞流水线,即使流水线里面只有定点指令;由于指令在 ROB 中是严格连续的,我们在重命名阶段提前为指令分配了 ROB 号,但仍然在后续阶段才判断 ROB 的入队仲裁,这样能够在不损失 ROB 实际可用项数、不影响性能的情况下通过提前一级锁存 ROB 号、增加几十个寄存器的方式完成时序优化。