加载使用冒险的思考

加载/使用冒险

暂停(Stalling)是一种通过保持程序计数器(PC)保持不变来实现暂停执行流水线的一条或多条指令的技术

气泡(bubble)是通过将某一流水线阶段正在执行的指令替换为对程序员可见状态(寄存器,内存,条件吗和程序状态)无影响的指令(如nop)

加载/使用冒险是指流水线前一条读内存的指令A(如mrmovq或popq)还处于执行阶段(此时没运行到访存阶段所以还没法读内存),但是流水线中该指令紧随其后的需要使用该数据的指令B就处在译码阶段了。

在该时刻,A指令未开始读内存,但是B指令就需要A读出来的数据,此时就发生了加载/使用冒险。该类型的冒险不能通过转发技术解决,因为在这个时间点读取内存的操作尚未发生(除非发生了时间穿越233333)。

会导致发生该类型的冒险的指令序列如下所示:

irmovq $128,%rdx
irmovq $3,%rcx
rmmovq %rcx, 0(%rdx)
irmovq $10, %rbx
mrmovq 0($rdx),%rax # Load %rax
addq %ebx, %eax     # Use %rax
halt

解决该类型的冒险的方案是:暂停 Use %rax(addq) 指令在Decode阶段的执行(这样做也会暂停Fetch阶段的执行,达到重复取同一条指令的效果),并向Execute阶段插入一个气泡以避免因为错误的数据导致addq执行异常,直到Load %rax(mrmovq)抵达Memory阶段。如下图所示:

这种使用Stalling和bubble来避免Load/Use冒险的方法称为加载互锁(Load interlock)。加载互锁和转发结合起来足以处理所有的数据冒险。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据