[IT/数码] GPU 指令格式 [上]

[复制链接]
查看11 | 回复0 | 昨天 18:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 hdy 于 2025-5-23 18:42 编辑

RISCV 指令与ROB
183938b702fceb.png
[size=1em]RISCV精简指令集的指令格式如上图所示,最低0-6位是opcode,一旦译码器读取这7bit,就可以直接确定指令类型。
我们知道CPU的指令之间存在data hazard,structure hazard,control hazard,就是我们总说的数据依赖,结构依赖和控制依赖。为了解决这些问题,寄存器重命名可以解决假依赖,ROB可以解决真实的依赖。
183941d63ce906.png
[RISCV ROB]
如上图所示,CPU中的ROB使用valid, busy等flag进行标记。那么我们在设计GPU时,是否也是按照CPU的方法,每个小核都设计ROB呢?考虑到下图中GPU大量繁复的SM,CUDA Core架构,每个Core都设计ROB,这会带来很大的挑战。
183957ed69cdad.png



GPU的control information
既然硬件实现上存在困难,那么我们使用软件实现,将指令的依赖关系编码到指令中,就可以解决。于是编译器在GPU的指令中增加control information,显式的将指令之间的依赖关系进行编码,即可以避免设计复杂的硬件。
184003c1a44b1d.png
2012年的Kepler架构引进了control words用于编译器编码依赖信息,7条指令共享一条control word.随着设计变得愈发复杂,在Pascal和Maxwell架构中3条指令共享一条control word,如下图所示:3条64bit的指令共享第一条64bit的control word。其中每个instruction占用21bit的control word。 184005503c45d2.png
摘自[1]
目前的最新的架构,每条指令都具有自己的control word,这样每条指令的长度增长到128bit。
接下来的内容十分硬核,希望大家不要放弃


Control Information
下图中最新的GPU架构中,每条指令的内部都有专门的control introformation,下图中从灰色到紫色的部分均为control information。
1840098fbe94b7.png
下面我们来解释control information是如何工作的。
针对上图中的最后一条指令IADD3,其source reg为R1, R5,R7,其dest reg为 R2。这里为了简便,只考虑0x80的IADD3 和 前三条指令之间的依赖关系。
  • 第一条PC=0x50 LD的dest reg为R5,因此IADD3和 0x50 LD 存在RAW依赖。
  • 第二条PC=0x60 LD的dest reg为R7,因此IADD3和 0x60 LD 存在RAW依赖。
  • 第三条PC=0x70 LD的source reg为R2,因此IADD3和 PC=0x70 LD存在WAR依赖。
  • 第二条PC=0x60 LD的 source reg为R2,因此IADD3和 PC=0x60 LD存在WAR依赖。

为了解决上述a)b)的依赖关系,我们可以看到在控制信息中,PC=0x50和0x60的指令的控制信息中,存在:
184010f7229d9d.png
这意味着指令0x50和0x60在发射时,会将 3号Dependence Counter累加1,而0x80在发射时,根据指令中的这一mask信息:
184012a0b71cc6.png
0bit和3bit为1,即0x80 IADD3指令需要判断
  • 0号dependence counter
  • 3号dependence counter
为0,才可以发射。如果非0,意味着存在dependence依赖。等到0x50和0x60执行完毕,write-back完毕,写入到对应的R5和R7寄存器时,会递减3号Dependence Counter至0,表示该reg 已经ready,后续指令可以读取。那么0号寄存器呢?
18401420f8db06.png
如果你还记得c)和d)依赖关系,0x80 IADD3会写入0x60和0x70读取的source reg,因此0x60和0x70 指令使用了0号dependence counter,在发射时进行累加,读取source reg完毕后,会将0号dependence counter递减清零。表示该reg 已经读取完毕,后续指令可以写覆盖。总结即为:
  • 0号dependence counter被选择用于解决WAR依赖,older instruction发射时累加,读取source完毕后递减
  • 3号dependence counter被选择用于解决RAW依赖,older instruction发射时累加,写回destination完毕后递减
  • younger instruct中的control 信息显式编码了需要判断0号和3号 dependence counter,等待清零后发射

当然,0号和3号具体使用哪个dependence counter并不是固定的,由编译器进行选择。
这样,通过显式的将依赖信息进行编码,指令不需要去查询更新每个source,dest的状态,只需要查询,更新对应的dependence counter即可。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

hdy

546

主题

343

回帖

617

积分

二级逆天

积分
617